จะบันทึกเวลาดำเนินการของเมธอดเป็นมิลลิวินาทีได้อย่างไร


222

มีวิธีในการพิจารณาว่าต้องใช้เวลาเท่าใดในการประมวลผล (เป็นมิลลิวินาที)?


2
คุณมีโอกาสถามเพราะคุณต้องการค้นหาสิ่งที่คุณสามารถเพิ่มประสิทธิภาพเพื่อให้เร็วขึ้น?
Mike Dunlavey

1
ใช่ฉันใช้ UIWebView ที่กำลังโหลดบางหน้า ฉันต้องการเพิ่มประสิทธิภาพ pageloading โดยการตรวจสอบเวลาที่วิธีการโหลดหน้า 1 ถึงหน้า 10
dan

2
สิ่งนี้ดูเหมือนจะซ้ำซ้อนกับคำถามนี้: stackoverflow.com/questions/889380/…
Brad Larson

@BradLarson แม้ว่ามันจะซ้ำกัน แต่คำถามอื่นมีคำตอบที่ดีกว่านั่นคือคำตอบที่เด่นชัดไม่ได้แนะนำให้ใช้ (ไม่ถูกต้อง) NSDate แต่แทนที่จะอธิบายได้ดีว่าทำไม NSDate จึงเป็นวิธีที่ผิดที่ต้องทำเพื่อจุดประสงค์นี้
โทมัส Tempelmann

คำตอบ:


437
NSDate *methodStart = [NSDate date];

/* ... Do whatever you need to do ... */

NSDate *methodFinish = [NSDate date];
NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];
NSLog(@"executionTime = %f", executionTime);

สวิฟท์:

let methodStart = NSDate()

/* ... Do whatever you need to do ... */

let methodFinish = NSDate()
let executionTime = methodFinish.timeIntervalSinceDate(methodStart)
print("Execution time: \(executionTime)")

Swift3:

let methodStart = Date()

/* ... Do whatever you need to do ... */

let methodFinish = Date()
let executionTime = methodFinish.timeIntervalSince(methodStart)
print("Execution time: \(executionTime)")

ใช้งานง่ายและมีความแม่นยำย่อยมิลลิวินาที


3
@PeterWarbo NSTimeInterval เป็น typedef ของ double และถูกกำหนดเป็นวินาที - ดูdeveloper.apple.com/library/mac/#documentation/Cocoa/Reference/…
Ben Lings

5
คุณสามารถบันทึกค่านี้ด้วย% f - NSLog ("executionTime =% f", executionTime);
Tony

1
@Tony คุณลืม @,NSLog(@"executionTime = %f", executionTime);
John Riselvato

6
ฉันเพิ่งเปรียบเทียบNSDateและmach_absolute_time()ที่ระดับประมาณ 30ms 27 กับ 29, 36 กับ 39, 43 กับ 45 ก็ง่ายที่จะใช้สำหรับฉันและผลที่ได้ก็เพียงพอที่คล้ายกันที่จะไม่รำคาญกับNSDate mach_absolute_time()
nevan king

5
อะไรก็ตามที่อิงกับ NSDate นั้นไม่ปลอดภัยสำหรับการวัดเวลาที่ผ่านไปเพราะเวลาสามารถกระโดดได้แม้ย้อนกลับ วิธีที่ปลอดภัยกว่าคือการใช้ mach_absolute_time ดังที่แสดงในคำตอบอื่น ๆ ที่นี่ อันนี้ควรถูกลดระดับลงเพราะเป็นตัวอย่างที่ไม่ดี ดูคำตอบที่เกี่ยวข้องซึ่งอธิบายรายละเอียดทั้งหมดนี้ได้ที่: stackoverflow.com/a/30363702/43615
Thomas Tempelmann

252

ต่อไปนี้เป็นมาโครสองบรรทัดที่ฉันใช้:

#define TICK   NSDate *startTime = [NSDate date]
#define TOCK   NSLog(@"Time: %f", -[startTime timeIntervalSinceNow])

ใช้มันแบบนี้:

TICK;

/* ... Do Some Work Here ... */

TOCK;

13
ฮ่าฮ่า ฉันชอบมัน!
bobmoff

5
สิ่งที่ทำให้สิ่งนี้ดีมากคือติ๊กต็อกเป็นวลีที่น่าจดจำที่การบันทึกแทบไม่ต้องคิดอะไรเลย
John Riselvato

30
#define TOCK NSLog(@"%s Time: %f", __func__, -[startTime timeIntervalSinceNow])ทำให้คำตอบนี้กลับมาพร้อมกับฟังก์ชั่นจับเวลาที่ใช้ฉันพบว่ามีประโยชน์ถ้าฉันใช้ TICK TOCK เพื่อฟังก์ชั่นหลาย ๆ ครั้ง
golmschenk

3
ความคิดที่ดี @gmsmsk! นอกจากนี้คุณยังสามารถตรวจสอบ__PRETTY_FUNCTION__และ__LINE__ถ้าคุณต้องการข้อมูลรายละเอียดเพิ่มเติม
Ron

50

สำหรับช่วงเวลาที่ละเอียดใน OS X คุณควรใช้mach_absolute_time( )ประกาศใน<mach/mach_time.h>:

#include <mach/mach_time.h>
#include <stdint.h>

// Do some stuff to setup for timing
const uint64_t startTime = mach_absolute_time();
// Do some stuff that you want to time
const uint64_t endTime = mach_absolute_time();

// Time elapsed in Mach time units.
const uint64_t elapsedMTU = endTime - startTime;

// Get information for converting from MTU to nanoseconds
mach_timebase_info_data_t info;
if (mach_timebase_info(&info))
   handleErrorConditionIfYoureBeingCareful();

// Get elapsed time in nanoseconds:
const double elapsedNS = (double)elapsedMTU * (double)info.numer / (double)info.denom;

แน่นอน caveats ปกติเกี่ยวกับการวัดที่ละเอียดใช้; คุณน่าจะดีที่สุดที่จะเรียกใช้งานรูทีนภายใต้การทดสอบหลายครั้งและเฉลี่ย / ทำการประมวลผลขั้นต่ำ / รูปแบบอื่น ๆ

นอกจากนี้โปรดทราบว่าคุณอาจพบว่ามีประโยชน์มากขึ้นสำหรับโปรไฟล์แอปพลิเคชันของคุณที่ทำงานโดยใช้เครื่องมือเช่น Shark สิ่งนี้จะไม่ให้ข้อมูลเวลาที่แน่นอนแก่คุณ แต่มันจะบอกคุณว่าเปอร์เซ็นต์ของเวลาของแอปพลิเคชั่นนั้นถูกใช้ไปที่ไหนซึ่งมักจะมีประโยชน์มากกว่า (แต่ไม่เสมอไป)


1
กำลังพยายามทำให้เรื่องนี้ทำงานใน Swift ... ข้อเสนอแนะใด ๆ
zumzum

1
"ไม่เพียง แต่ ... แปลงเป็นสวิฟท์" - เน็ดสตาร์ค
stonedauwg

@zumzum ดูคำตอบของฉันสำหรับตัวอย่างของการทำสิ่งนี้ใน Swift
jbg

23

มีตัวห่อหุ้มที่สะดวกสำหรับmach_absolute_time()- เป็นCACurrentMediaTime()ฟังก์ชั่น

ต่างจากNSDateหรือCFAbsoluteTimeGetCurrent()ออฟเซ็ต mach_absolute_time()และCACurrentMediaTime()ขึ้นอยู่กับนาฬิกาของโฮสต์ภายในตัวชี้วัดที่แม่นยำ monatomic และไม่ขึ้นอยู่กับการเปลี่ยนแปลงในการอ้างอิงเวลาภายนอกเช่นที่เกิดจากเขตเวลาการประหยัดเวลากลางวันหรือการกระโดดวินาที


ObjC

CFTimeInterval startTime = CACurrentMediaTime();
// Do your stuff here
CFTimeInterval endTime = CACurrentMediaTime();
NSLog(@"Total Runtime: %g s", endTime - startTime);

รวดเร็ว

let startTime = CACurrentMediaTime()
// Do your stuff here
let endTime = CACurrentMediaTime()
print("Total Runtime: \(endTime - startTime) s")

3
ฉันคิดว่าคำตอบนี้สมควรได้รับผู้โหวตมากขึ้น NSDateมันเป็นวิธีที่ดีกว่าการใช้
ค่าเฉลี่ย Joe

12

ใน Swift ฉันใช้:

ใน Macros.swift ของฉันฉันเพิ่งเพิ่ม

var startTime = NSDate()
func TICK(){ startTime =  NSDate() }
func TOCK(function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__){
    println("\(function) Time: \(startTime.timeIntervalSinceNow)\nLine:\(line) File: \(file)")
}

ตอนนี้คุณสามารถโทรได้ทุกที่

TICK()

// your code to be tracked

TOCK()
  • รหัสนี้เป็นไปตามรหัสของรอนแปลเป็น Swift เขามีเครดิต
  • ฉันใช้วันที่เริ่มต้นในระดับโลกข้อเสนอแนะในการปรับปรุงใด ๆ ยินดีต้อนรับ

สิ่งนี้ควรเป็น\(-startTime.timeIntervalSinceNow)(สังเกตว่ามีค่าติดลบ)
มนุษย์หิมะ

9

ฉันรู้ว่านี่เป็นรุ่นเก่า แต่ฉันก็พบว่าตัวเองหลงทางอีกครั้งดังนั้นฉันคิดว่าฉันจะส่งตัวเลือกของฉันเองที่นี่

ทางออกที่ดีที่สุดคือการตรวจสอบโพสต์บล็อกของฉันเกี่ยวกับเรื่องนี้: กำหนดเวลาใน Objective-C: นาฬิกาจับเวลา

โดยทั่วไปฉันเขียนชั้นเรียนที่ไม่หยุดดูในวิธีขั้นพื้นฐานมาก แต่ถูกห่อหุ้มเพื่อที่คุณจะต้องทำสิ่งต่อไปนี้:

[MMStopwatchARC start:@"My Timer"];
// your work here ...
[MMStopwatchARC stop:@"My Timer"];

และคุณท้ายด้วย:

MyApp[4090:15203]  -> Stopwatch: [My Timer] runtime: [0.029]

ในบันทึก ...

ตรวจสอบโพสต์ของฉันอีกสักครู่หรือดาวน์โหลดได้ที่นี่: MMStopwatch.zip


7

ฉันใช้มาโครตามวิธีแก้ปัญหาของรอน

#define TICK(XXX) NSDate *XXX = [NSDate date]
#define TOCK(XXX) NSLog(@"%s: %f", #XXX, -[XXX timeIntervalSinceNow])

สำหรับบรรทัดของรหัส:

TICK(TIME1);
/// do job here
TOCK(TIME1);

เราจะเห็นในคอนโซลบางอย่างเช่น: TIME1: 0.096618


คำตอบของคุณไม่ได้แตกต่างจากคำตอบของรอนมากนักและฉันก็ไม่เห็นด้วยซ้ำ
Trilarion

2
คุณไม่สามารถใช้โซลูชันของ @ Ron ภายในบริบทเดียวสองครั้ง นี่คือเหตุผลหลักสำหรับมาโครนี้
Sergey Teryokhin

4

ฉันใช้การปรับใช้คลาสหน้าน้อยที่สุดซึ่งได้รับแรงบันดาลใจจากรหัสจากโพสต์บล็อกนี้ :

#import <mach/mach_time.h>

@interface DBGStopwatch : NSObject

+ (void)start:(NSString *)name;
+ (void)stop:(NSString *)name;

@end

@implementation DBGStopwatch

+ (NSMutableDictionary *)watches {
    static NSMutableDictionary *Watches = nil;
    static dispatch_once_t OnceToken;
    dispatch_once(&OnceToken, ^{
        Watches = @{}.mutableCopy;
    });
    return Watches;
}

+ (double)secondsFromMachTime:(uint64_t)time {
    mach_timebase_info_data_t timebase;
    mach_timebase_info(&timebase);
    return (double)time * (double)timebase.numer /
        (double)timebase.denom / 1e9;
}

+ (void)start:(NSString *)name {
    uint64_t begin = mach_absolute_time();
    self.watches[name] = @(begin);
}

+ (void)stop:(NSString *)name {
    uint64_t end = mach_absolute_time();
    uint64_t begin = [self.watches[name] unsignedLongLongValue];
    DDLogInfo(@"Time taken for %@ %g s",
              name, [self secondsFromMachTime:(end - begin)]);
    [self.watches removeObjectForKey:name];
}

@end

การใช้งานง่ายมาก:

  • เพียงแค่โทร [DBGStopwatch start:@"slow-operation"];ที่จุดเริ่มต้น
  • และ[DBGStopwatch stop:@"slow-operation"];หลังจากเสร็จสิ้นเพื่อให้ได้เวลา

3

คุณสามารถได้เวลาที่ดีจริง ๆ (วินาทีส่วนของวินาที) โดยใช้ระดับ StopWatch นี้ ใช้ตัวจับเวลาที่มีความแม่นยำสูงใน iPhone การใช้ NSDate จะช่วยให้คุณมีความแม่นยำที่สองเท่านั้น รุ่นนี้ได้รับการออกแบบมาโดยเฉพาะสำหรับการยกเลิกอัตโนมัติและวัตถุประสงค์ -c ฉันมีรุ่น c ++ เช่นกันหากจำเป็น คุณสามารถค้นหาค ++ รุ่นที่นี่

StopWatch.h

#import <Foundation/Foundation.h>


@interface StopWatch : NSObject 
{
    uint64_t _start;
    uint64_t _stop;
    uint64_t _elapsed;
}

-(void) Start;
-(void) Stop;
-(void) StopWithContext:(NSString*) context;
-(double) seconds;
-(NSString*) description;
+(StopWatch*) stopWatch;
-(StopWatch*) init;
@end

StopWatch.m

#import "StopWatch.h"
#include <mach/mach_time.h>

@implementation StopWatch

-(void) Start
{
    _stop = 0;
    _elapsed = 0;
    _start = mach_absolute_time();
}
-(void) Stop
{
    _stop = mach_absolute_time();   
    if(_stop > _start)
    {
        _elapsed = _stop - _start;
    }
    else 
    {
        _elapsed = 0;
    }
    _start = mach_absolute_time();
}

-(void) StopWithContext:(NSString*) context
{
    _stop = mach_absolute_time();   
    if(_stop > _start)
    {
        _elapsed = _stop - _start;
    }
    else 
    {
        _elapsed = 0;
    }
    NSLog([NSString stringWithFormat:@"[%@] Stopped at %f",context,[self seconds]]);

    _start = mach_absolute_time();
}


-(double) seconds
{
    if(_elapsed > 0)
    {
        uint64_t elapsedTimeNano = 0;

        mach_timebase_info_data_t timeBaseInfo;
        mach_timebase_info(&timeBaseInfo);
        elapsedTimeNano = _elapsed * timeBaseInfo.numer / timeBaseInfo.denom;
        double elapsedSeconds = elapsedTimeNano * 1.0E-9;
        return elapsedSeconds;
    }
    return 0.0;
}
-(NSString*) description
{
    return [NSString stringWithFormat:@"%f secs.",[self seconds]];
}
+(StopWatch*) stopWatch
{
    StopWatch* obj = [[[StopWatch alloc] init] autorelease];
    return obj;
}
-(StopWatch*) init
{
    [super   init];
    return self;
}

@end

คลาสมีสแตติก stopWatchวิธีการที่ส่งกลับวัตถุที่ autoreleased

เมื่อคุณโทรstartใช้secondsวิธีการเพื่อให้ได้เวลาที่ผ่านไป โทรstartอีกครั้งเพื่อเริ่มต้นใหม่ หรือstopเพื่อหยุดมัน คุณยังสามารถอ่านเวลา (โทรseconds) stopได้ตลอดเวลาหลังจากเรียก

ตัวอย่างในฟังก์ชั่น (การเรียกเวลาของการดำเนินการ)

-(void)SomeFunc
{
   StopWatch* stopWatch = [StopWatch stopWatch];
   [stopWatch Start];

   ... do stuff

   [stopWatch StopWithContext:[NSString stringWithFormat:@"Created %d Records",[records count]]];
}

"ความแม่นยำของวินาทีเท่านั้น" ของคุณไม่ถูกต้อง ในขณะที่ส่วนทั้งหมดของ NSTimeInterval คือวินาทีมันเป็นสองเท่า
สตีเว่นฟิชเชอร์

3

ฉันใช้รหัสนี้:

#import <mach/mach_time.h>

float TIME_BLOCK(NSString *key, void (^block)(void)) {
    mach_timebase_info_data_t info;
    if (mach_timebase_info(&info) != KERN_SUCCESS)
    {
        return -1.0;
    }

    uint64_t start = mach_absolute_time();
    block();
    uint64_t end = mach_absolute_time();
    uint64_t elapsed = end - start;

    uint64_t nanos = elapsed * info.numer / info.denom;
    float cost = (float)nanos / NSEC_PER_SEC;

    NSLog(@"key: %@ (%f ms)\n", key, cost * 1000);
    return cost;
}

2

ฉันใช้สิ่งนี้:

clock_t start, end;
double elapsed;
start = clock();

//Start code to time

//End code to time

end = clock();
elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;
NSLog(@"Time: %f",elapsed);

แต่ฉันไม่แน่ใจเกี่ยวกับ CLOCKS_PER_SEC บน iPhone คุณอาจต้องการที่จะทิ้งมันไว้


2
CLOCKS_PER_SEC บน iPhone เป็นค่าที่ไม่ถูกต้อง
mxcl

1
ดีแล้วที่รู้. ฉันจะใช้คำตอบของ Matthew ถ้าฉันต้องทำตอนนี้
David Kanarek

2

ตัวอย่างของการจับเวลาแบบละเอียดที่ใช้mach_absolute_time()ใน Swift 4:

let start = mach_absolute_time()

// do something

let elapsedMTU = mach_absolute_time() - start
var timebase = mach_timebase_info()
if mach_timebase_info(&timebase) == 0 {
    let elapsed = Double(elapsedMTU) * Double(timebase.numer) / Double(timebase.denom)
    print("render took \(elapsed)")
}
else {
    print("timebase error")
}

2

ตกลงถ้าเป้าหมายของคุณคือค้นหาสิ่งที่คุณสามารถแก้ไขได้เพื่อให้เร็วขึ้นนั่นคือเป้าหมายที่แตกต่างกันเล็กน้อย การวัดเวลาที่ฟังก์ชั่นใช้เป็นวิธีที่ดีในการตรวจสอบว่าสิ่งที่คุณทำมีความแตกต่างหรือไม่ แต่เพื่อค้นหาว่าคุณต้องใช้เทคนิคอื่น นี่คือสิ่งที่ฉันแนะนำและฉันรู้ว่าคุณสามารถทำได้บน iPhone

แก้ไข: ผู้ตรวจทานแนะนำให้ฉันอธิบายคำตอบอย่างละเอียดดังนั้นฉันจึงพยายามคิดหาวิธีพูดสั้น ๆ
โปรแกรมโดยรวมของคุณใช้เวลานาฬิกามากพอที่จะรบกวนคุณ สมมติว่านั่นคือNวินาที
คุณสมมติว่าคุณสามารถเร่งความเร็วได้ วิธีเดียวที่คุณสามารถทำได้คือการทำให้มันไม่ทำสิ่งที่มันทำในเวลานั้นคิดเป็นmวินาที
ตอนแรกคุณไม่รู้ว่ามันคืออะไร คุณสามารถเดาได้เหมือนโปรแกรมเมอร์ทุกคนทำ แต่อาจเป็นอย่างอื่นได้ง่าย นี่คือวิธีที่คุณจะพบ:

เนื่องจากสิ่งนั้นไม่ว่าจะเป็นเศษส่วนm / Nของเวลาหมายความว่าถ้าคุณหยุดชั่วคราวโดยการสุ่มความน่าจะเป็นคือm / Nที่คุณจะจับมันในการกระทำสิ่งนั้น แน่นอนว่ามันอาจจะทำอย่างอื่น แต่หยุดมันชั่วคราวและดูว่ามันกำลังทำอะไรอยู่
ตอนนี้ทำมันอีกครั้ง หากคุณเห็นว่ามันทำสิ่งเดียวกันอีกครั้งคุณก็อาจจะสงสัยมากขึ้น

ทำ 10 ครั้งหรือ 20 ทีนี้ถ้าคุณเห็นมันทำอะไรบางอย่าง (ไม่ว่าคุณจะอธิบาย) ในหลาย ๆ ช่วงหยุดชั่วคราวคุณสามารถกำจัดคุณรู้สองสิ่ง คุณรู้ว่าใช้เวลาแค่ไหน แต่คุณรู้ว่าต้องแก้ไขอย่างไร
หากคุณต้องการทราบว่าจะประหยัดเวลามากเพียงใดนั่นเป็นเรื่องง่าย วัดก่อนแก้ไขและวัดหลังจาก หากคุณผิดหวังจริงๆให้ถอยออกไปแก้ไข

คุณเห็นว่ามันแตกต่างจากการวัดหรือไม่? มันหาไม่ได้วัด การทำโปรไฟล์ส่วนใหญ่ขึ้นอยู่กับการวัดให้มากที่สุดเท่าที่จะเป็นไปได้ใช้เวลาเท่าใดราวกับว่าเป็นเรื่องสำคัญและส่งคลื่นปัญหาของการระบุสิ่งที่ต้องแก้ไข การสร้างโปรไฟล์ไม่พบปัญหาทุกปัญหา แต่วิธีนี้จะพบปัญหาทุกปัญหาและเป็นปัญหาที่คุณไม่พบว่าทำให้คุณเจ็บปวด


0

นี่เป็นอีกวิธีหนึ่งใน Swift การทำเช่นนั้นโดยใช้คำหลักที่เลื่อนออกไป

func methodName() {
  let methodStart = Date()
  defer {
    let executionTime = Date().timeIntervalSince(methodStart)
    print("Execution time: \(executionTime)")
  }
  // do your stuff here
}

จากdocsของ Apple : คำสั่ง defer ใช้สำหรับการเรียกใช้งานโค้ดก่อนโอนการควบคุมโปรแกรมนอกขอบเขตที่คำสั่ง defer ปรากฏขึ้น

สิ่งนี้คล้ายกับการลอง / ปิดกั้นในที่สุดโดยมีข้อได้เปรียบในการจัดกลุ่มรหัสที่เกี่ยวข้อง


0

ฉันใช้สิ่งนี้ในห้องสมุดของฉัน ( Swift 4.2 ):

public class PrintTimer {
    let start = Date()
    let name: String

    public init(file: String=#file, line: Int=#line, function: String=#function, name: String?=nil) {
        let file = file.split(separator: "/").last!
        self.name = name ?? "\(file):\(line) - \(function)"
    }

    public func done() {
        let end = Date()
        print("\(self.name) took \((end.timeIntervalSinceReferenceDate - self.start.timeIntervalSinceReferenceDate).roundToSigFigs(5)) s.")
    }
}

... จากนั้นเรียกใช้วิธีการเช่น:

func myFunctionCall() {
    let timer = PrintTimer()
    // ...
    timer.done()
}

... ซึ่งในลักษณะนี้ในคอนโซลหลังจากทำงาน:

MyFile.swift:225 - myFunctionCall() took 1.8623 s.

ไม่รัดกุมเหมือน TICK / TOCK ด้านบน แต่ชัดเจนพอที่จะดูว่ามันกำลังทำอะไรและรวมถึงสิ่งที่ถูกกำหนดเวลาโดยอัตโนมัติ (ตามไฟล์บรรทัดที่จุดเริ่มต้นของเมธอดและชื่อฟังก์ชัน) เห็นได้ชัดว่าถ้าฉันต้องการรายละเอียดเพิ่มเติม (เช่นถ้าฉันไม่เพียงแค่กำหนดเวลาการเรียกเมธอดตามปกติ แต่แทนที่จะกำหนดเวลาบล็อกภายในเมธอดนั้น) ฉันสามารถเพิ่มพารามิเตอร์ "name =" Foo "" ใน PrintTimer init เพื่อตั้งชื่อบางสิ่งนอกเหนือจากค่าเริ่มต้น


-1

เนื่องจากคุณต้องการปรับการย้ายเวลาจากหน้าหนึ่งไปอีกหน้าหนึ่งใน UIWebView ไม่ได้หมายความว่าคุณต้องการเพิ่มประสิทธิภาพของ Javascript ที่ใช้ในการโหลดหน้าเหล่านี้หรือไม่

ด้วยเหตุนี้ฉันจะดู WebKit Profiler อย่างที่พูดถึงที่นี่:

http://www.alertdebugging.com/2009/04/29/building-a-better-javascript-profiler-with-webkit/

อีกวิธีคือการเริ่มต้นในระดับสูงและคิดว่าคุณสามารถออกแบบหน้าเว็บที่เป็นปัญหาเพื่อลดเวลาในการโหลดโดยใช้การโหลดหน้าสไตล์ AJAX แทนที่จะรีเฟรชหน้าเว็บทั้งหมดในแต่ละครั้ง


-1
struct TIME {

    static var ti = mach_timebase_info()
    static var k: Double = 1
    static var mach_stamp: Double {

        if ti.denom == 0 {
            mach_timebase_info(&ti)
            k = Double(ti.numer) / Double(ti.denom) * 1e-6
        }
        return Double(mach_absolute_time()) * k
    }
    static var stamp: Double { return NSDate.timeIntervalSinceReferenceDate() * 1000 }
}

do {
    let mach_start = TIME.mach_stamp
    usleep(200000)
    let mach_diff = TIME.mach_stamp - mach_start

    let start = TIME.stamp
    usleep(200000)
    let diff = TIME.stamp - start

    print(mach_diff, diff)
}

-1

นี่คือโซลูชัน Swift 3 สำหรับการตัดรหัสที่ใดก็ได้เพื่อค้นหากระบวนการทำงานที่ยาวนาน

var increment: Int = 0

var incrementTime = NSDate()

struct Instrumentation {
    var title: String
    var point: Int
    var elapsedTime: Double

    init(_ title: String, _ point: Int, _ elapsedTime: Double) {
        self.title = title
        self.point = point
        self.elapsedTime = elapsedTime
    }
}

var elapsedTimes = [Instrumentation]()

func instrument(_ title: String) {
    increment += 1
    let incrementedTime = -incrementTime.timeIntervalSinceNow
    let newPoint = Instrumentation(title, increment, incrementedTime)
    elapsedTimes.append(newPoint)
    incrementTime = NSDate()
}

การใช้งาน: -

instrument("View Did Appear")

print("ELAPSED TIMES \(elapsedTimes)")

ตัวอย่างผลลัพธ์: -

ELAPSED TIMES [MyApp.SomeViewController.Instrumentation (ชื่อเรื่อง: "มุมมองเริ่มโหลดไม่ได้", จุด: 1, elapsedTime: 0.040504038333892822), MyApp.SomeViewController.Instrumentation (ชื่อเรื่อง: "เสร็จสิ้นการเพิ่มตัวอย่างย่อย", จุด: 2, elapsedTime: 0.0105850) MyApp.SomeViewController.Instrumentation (ชื่อเรื่อง: "View Did ปรากฏ", จุด: 3, เวลาที่ผ่านไป: 0.56564098596572876)]


-1

คำตอบมากมายนั้นแปลกและไม่ได้ให้ผลลัพธ์เป็นมิลลิวินาที (แต่ในเสี้ยววินาทีหรืออย่างอื่น):

นี่คือสิ่งที่ฉันใช้เพื่อรับ MS (MILLISECONDS):

สวิฟท์:

let startTime = NSDate().timeIntervalSince1970 * 1000

// your Swift code

let endTimeMinusStartTime = NSDate().timeIntervalSince1970 * 1000 - startTime
print("time code execution \(endTimeMinStartTime) ms")

Objective-C:

double startTime = [[NSDate date] timeIntervalSince1970] * 1000.0;

// your Objective-C code

double endTimeMinusStartTime = [[NSDate date] timeIntervalSince1970] * 1000.0 - startTime;
printf("time code execution %f ms\n", endTimeMinusStartTime );

-1

สำหรับ Swift 4 เพิ่มเป็น Delegate ให้กับคลาสของคุณ:

public protocol TimingDelegate: class {
    var _TICK: Date?{ get set }
}

extension TimingDelegate {
    var TICK: Date {
        _TICK = Date()
        return(_TICK)!
     }

    func TOCK(message: String)  {

        if (_TICK == nil){
            print("Call 'TICK' first!")
        }

        if (message == ""){
            print("\(Date().timeIntervalSince(_TICK!))")
        }
        else{
            print("\(message): \(Date().timeIntervalSince(_TICK!))")
        }
    }
}

เพิ่มในชั้นเรียนของเรา:

class MyViewcontroller: UIViewController, TimingDelegate

จากนั้นเพิ่มชั้นเรียนของคุณ:

var _TICK: Date?

เมื่อคุณต้องการเวลาบางสิ่งเริ่มต้นด้วย:

TICK

และจบลงด้วย:

TOCK("Timing the XXX routine")

คุณอ่านคำตอบและความคิดเห็นแล้วหรือยัง? อย่าใช้ Date สำหรับสิ่งนี้!
แมตต์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.