2010-08-22 3 views
13

Я ищу код с высоким разрешением для iPhone, чтобы сделать некоторые тайминги производительности. Я хотел бы написать такой код:Таймер с высоким разрешением для iPhone?

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

Почему бы просто не использовать 'getrusage()'? Все, что работает на C, будет работать в Objective-C. –

+1

Потому что есть отличный способ Какао для того, чтобы делать то же самое. – lucius

ответ

26

Посмотрите на mach_absolute_time() в заголовке mach/mach_time.h.

Не используйте NSDate. NSDate даже не гарантированно не возвращаться назад, когда ntp делает свою вещь.

(Устройства могут иметь дрейф часов.Если устройство iOS быстро сдвигается на несколько секунд, тогда, когда NTP исправляет этот дрейф, вы увидите, что часы внезапно возвращаются назад на несколько секунд. Очень плохо для использования времени. Mach_time использует счетчик что не когда-нибудь исправляется NTP, таким образом, не может идти в обратном направлении, таким образом, гораздо лучше времени.)

+1

'NSDate' просто возвращает двойной, который подсчитывает секунды с 1 января 2001 года. Для времени секундомера отрицательное время просто не произойдет, поэтому я не вижу необходимости в накладных расходах, связанных с приведением' mach_absolute_time() 'в ваш код - [оба реализованы здесь] (http://stackoverflow.com/a/12553393/111307). – bobobobo

+3

@bobobobo: количество секунд устройства с 1 января 2001 года иногда корректируется NTP. Таким образом, он может быть немонотонным на любом устройстве, у которого есть часы-часы, которые иногда дрейфуют быстро, а также сетевое соединение, которое может исправить этот дрейф. – hotpaw2

+0

В итоге я использовал mach_absolute_time(). Я нашел небольшой класс, используя его, [здесь] (http://zpasternack.blogspot.com/2012/07/high-resolution-timing-in-cocoa.html). – zpasternack

5

Используйте NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate], чтобы получить время начала, а затем NSLog (@"Operation took %f seconds.", [NSDate timeIntervalSinceReferenceDate] - startTime); в конце.

+1

Это прекрасно работает, спасибо! Я не знал, что NSDate имеет такой уровень точности. – zpasternack

16

Лучшим вариантом является CACurrentMediaTime(), который использует mach_absolute_time(), но преобразует его в CFTimeInterval (т.е. время в секундах, как двойной) для вас.

+0

Требуется ['#import '] (https://stackoverflow.com/q/729094). – Pang

8

Вот мой ответ для таймеров с тактовой частотой mach_absolute_time(), основанный на методе вычисления shown here и NSDate. Фактически они одинаковы с точки зрения точности.

Mach версия

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 версия

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 
} 

Результаты:

Примечание разрешение на обоих из них действительно хорошо.

 

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 

* Если вы посмотрите на историю редактирования этого поста, вы можете увидеть опасность использования float в месте double!

+0

Вы забыли добавить init = true; в machGetClockS(). –

+0

@AndrewSmith Отличная точка! Исправлена. – bobobobo

+0

Не очень хорошая проверка временного разрешения, так как вы протестировали без мониторинга проводки для любых сетевых подключений NTP, что иногда может действительно испортиться с результатами NSDate. – hotpaw2

 Смежные вопросы

  • Нет связанных вопросов^_^