我正在寻找用于iPhone的高分辨率定时代码,以便进行一些性能定时。我想编写如下代码:
HighResolutionTimer* myTimer = [[HighResolutionTimer alloc]init];
[myTimer start];
[self doSomeLengthyOperation];
NSLog( @"doSomeLengthyOperation took %f seconds", [myTimer elapsedTime] );
我正在寻找用于iPhone的高分辨率定时代码,以便进行一些性能定时。我想编写如下代码:
HighResolutionTimer* myTimer = [[HighResolutionTimer alloc]init];
[myTimer start];
[self doSomeLengthyOperation];
NSLog( @"doSomeLengthyOperation took %f seconds", [myTimer elapsedTime] );
请查阅mach/mach_time.h头文件中的mach_absolute_time()函数。
不要使用NSDate。当ntp工作时,NSDate甚至不能保证不偶尔出现向后移动的情况。
(设备可能存在时钟漂移。如果iOS设备快速漂移几秒钟,那么当NTP纠正此漂移时,您会看到时钟突然向后退几秒钟。对于计时应用非常不利。mach_time使用一个计数器,该计数器不会受到NTP校正,因此无法向后移动,因此更适合计时。)
NSDate
只返回一个双精度浮点数,它计算自2001年1月1日以来的秒数。对于秒表计时,不会出现负时间,因此我认为没有必要将 mach_absolute_time()
引入您的代码中 -- 两者都在这里实现。 - bobobobo一种更好的选择是使用CACurrentMediaTime()
,它使用mach_absolute_time()
,但会自动将其转换为CFTimeInterval
(即以浮点数形式表示的秒数)。
以下是使用mach_absolute_time()
和NSDate
的时钟计时器的答案,基于此处所示的计算方法。它们在精度方面实际上是相同的。
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
}
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模拟器,运行帧速计数(以毫秒为单位(*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硬件采样: 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
的危险!
使用NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate]
获取开始时间,然后在结尾处使用NSLog(@"操作花费%f秒。", [NSDate timeIntervalSinceReferenceDate] - startTime);
。
getrusage()
?在 C 中可用的任何东西都可以在 Objective-C 中使用。 - Carl Norum