2010-08-22 33 views
13

Tôi đang tìm mã thời gian có độ phân giải cao cho iPhone, để thực hiện một số thời gian hiệu suất. Tôi muốn viết mã như thế này:Hẹn giờ có độ phân giải cao cho iPhone?

HighResolutionTimer* myTimer = [[HighResolutionTimer alloc]init]; 
[myTimer start]; 
[self doSomeLengthyOperation]; 
NSLog(@"doSomeLengthyOperation took %f seconds", [myTimer elapsedTime]); 
+1

Tại sao không chỉ sử dụng 'getrusage()'? Bất cứ điều gì làm việc trong C sẽ làm việc trong Objective-C. –

+1

Bởi vì có một phương pháp Cocoa hoàn hảo tốt để làm điều tương tự. – lucius

Trả lời

26

Nhìn vào mach_absolute_time() trong tiêu đề mach/mach_time.h.

Không sử dụng NSDate. NSDate thậm chí không được bảo đảm để không đi ngược lại đôi khi, khi ntp làm điều của nó. Nếu thiết bị iOS trôi nhanh trong vài giây, khi NTP sửa lỗi trôi dạt này, bạn sẽ thấy đồng hồ đột ngột lùi lại vài giây. Rất xấu khi sử dụng thời gian. điều đó không bao giờ có được điều chỉnh bởi NTP, do đó không thể đi thụt lùi, vậy là tốt hơn nhiều cho thời gian.)

+1

'NSDate' chỉ trả về giá trị gấp đôi kể từ ngày 1 tháng 1 năm 2001. Đối với thời gian đồng hồ bấm giờ, thời gian tiêu cực sẽ không xảy ra, vì vậy tôi không cần phải nạp tiền' mach_absolute_time() 'vào mã của bạn - [cả hai được thực hiện ở đây] (http://stackoverflow.com/a/12553393/111307). – bobobobo

+3

@bobobobo: Số giây của thiết bị kể từ ngày 1 tháng 1 năm 2001 đôi khi được NTP điều chỉnh ngược. Vì vậy, nó có thể không đơn điệu trên bất kỳ thiết bị nào có một tinh thể đồng hồ đôi khi trôi nhanh, cộng với kết nối mạng có thể khắc phục sự cố này. – hotpaw2

+0

Tôi đã sử dụng mach_absolute_time(). Tôi tìm thấy một lớp học nhỏ sử dụng nó, [ở đây] (http://zpasternack.blogspot.com/2012/07/high-resolution-timing-in-cocoa.html). – zpasternack

5

Sử dụng NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate] để có được một thời gian bắt đầu, và sau đó NSLog (@"Operation took %f seconds.", [NSDate timeIntervalSinceReferenceDate] - startTime); ở cuối.

+1

Điều đó hoạt động hoàn hảo, cảm ơn! Tôi đã không nhận ra NSDate có mức độ chính xác này. – zpasternack

16

một lựa chọn tốt hơn là CACurrentMediaTime() trong đó sử dụng mach_absolute_time() nhưng chuyển nó đến một CFTimeInterval (ví dụ, thời gian trong vài giây như một đôi) cho bạn.

+0

Yêu cầu ['#import '] (https://stackoverflow.com/q/729094). – Pang

8

Đây là câu trả lời của tôi cho đồng hồ bấm giờ sử dụng cả hai mach_absolute_time(), dựa trên phương pháp tính toán shown hereNSDate. Thực sự là giống nhau về độ chính xác.

Mach phiên bản

double machGetClockS() 
{ 
    static bool init = 0 ; 
    static mach_timebase_info_data_t tbInfo ; 
    static double conversionFactor ; 
    if(!init) 
    { 
    init = 1 ; 
    // get the time base 
    mach_timebase_info(&tbInfo) ; 
    conversionFactor = tbInfo.numer/(1e9*tbInfo.denom) ; // ns->s 
    } 

    return mach_absolute_time() * conversionFactor ; // seconds 
} 

double machGetClockDiffS() 
{ 
    static double lastTime = 0; 

    double currentTime = machGetClockS() ; 

    double diff = currentTime - lastTime ; 

    lastTime = currentTime ; // update for next call 

    return diff ; // that's your answer 
} 

NSTimeInterval phiên bản

double getClockS() 
{ 
    return [NSDate timeIntervalSinceReferenceDate] ; // NSTimeInterval is always specified in seconds 
} 

double getClockDiffS() 
{ 
    static double lastTime = 0 ; 

    double currentTime = getClockS() ; 

    double diff = currentTime - lastTime ; 

    lastTime = currentTime ; // update for next call 

    return diff ; // that's your answer 
} 

Kết quả:

Lưu ý độ phân giải trên cả hai trong số đó là thực sự tốt.

 

IOS SIMULATOR, running frame rate counts (in milliseconds (*1000.0)) 

MACH_ABS_TIME/NSTimeIntervals 
58.557001/58.552980 
40.558007/40.562987 
52.207822/52.200019 
33.742197/33.742011 
38.498912/38.504004 
48.872679/48.868001 
45.012602/45.011997 
57.858432/57.865977 
25.044615/25.038004 


IPAD HARDWARE SAMPLINGS: 
33.415041/33.416033 
33.240167/33.239007 
33.357542/33.357978 
33.302833/33.302009 
33.506750/33.509016 
33.582250/33.582985 
33.233958/33.232987 
33.239042/33.237994 

* Nếu bạn nhìn vào lịch sử chỉnh sửa của bài viết này, bạn có thể thấy sự nguy hiểm của việc sử dụng float vào vị trí của một double!

+0

Bạn quên thêm init = true; trong machGetClockS(). –

+0

@AndrewSmith Điểm tuyệt vời! Đã sửa. – bobobobo

+0

Không phải là một thử nghiệm tốt về độ phân giải thời gian, kể từ khi bạn kiểm tra mà không giám sát wireshark cho bất kỳ kết nối mạng NTP, mà đôi khi có thể thực sự gây rối với các kết quả NSDate. – hotpaw2

Các vấn đề liên quan