Таймер с высоким разрешением для iPhone?
Я ищу код времени с высоким разрешением для iPhone, чтобы сделать некоторые тайминги производительности. Я бы хотел написать такой код:
HighResolutionTimer* myTimer = [[HighResolutionTimer alloc]init];
[myTimer start];
[self doSomeLengthyOperation];
NSLog( @"doSomeLengthyOperation took %f seconds", [myTimer elapsedTime] );
Ответы
Ответ 1
Посмотрите на mach_absolute_time() в заголовке mach/mach_time.h.
Не используйте NSDate. NSDate даже не гарантированно не возвращаться назад, когда ntp делает свою вещь.
(Устройства могут иметь дрейф часов.Если устройство iOS быстро сдвигается на несколько секунд, тогда, когда NTP исправляет этот дрейф, вы увидите, что часы внезапно возвращаются назад на несколько секунд. Очень плохо для использования времени. mach_time использует счетчик, который никогда не исправляется NTP, поэтому не может вернуться в обратном направлении, поэтому гораздо лучше для выбора времени.)
Ответ 2
Лучшим вариантом является CACurrentMediaTime()
, который использует mach_absolute_time()
, но преобразует его в CFTimeInterval
(т.е. время в секундах как двойное) для вас.
Ответ 3
Здесь мой ответ для таймеров синхронизации, использующих как mach_absolute_time()
, на основе метода вычисления показанного здесь, так и 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 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 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
!
Ответ 4
Используйте NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate]
, чтобы получить время начала, а затем NSLog (@"Operation took %f seconds.", [NSDate timeIntervalSinceReferenceDate] - startTime);
в конце.