简体   繁体   English

iPhone的高分辨率计时器?

[英]High-resolution timer for iPhone?

I'm looking for high-resolution timing code for iPhone, in order to do some performance timings. 我正在寻找iPhone的高分辨率计时代码,以执行一些性能计时。 I'd like to write code like this: 我想写这样的代码:

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

Look into mach_absolute_time() in the mach/mach_time.h header. 在mach / mach_time.h标头中查看mach_absolute_time()。

Don't use NSDate. 不要使用NSDate。 NSDate isn't even guaranteed to not go backwards occasionally, when ntp does its thing. 当ntp执行其操作时,NSDate甚至不保证偶尔不会倒退。

(Devices can have clock drift. If the iOS device drifts fast a few seconds, then when NTP corrects this drift, you will see the clock suddenly go backwards a few seconds. Very bad for timing use. mach_time uses a counter that doesn't ever get corrected by NTP, thus can't go backwards, thus is far better for timing.) (设备可能会有时钟漂移。如果iOS设备漂移了几秒钟,那么当NTP纠正这种漂移时,您会看到时钟突然倒退了几秒钟。这对计时使用非常不利。mach_time使用的计数器不会永远不会被NTP纠正,因此不会向后退,因此计时效果会更好。)

更好的选择是CACurrentMediaTime() ,它使用mach_absolute_time()但会为您将其转换为CFTimeInterval (即,以秒为单位的时间为两倍)。

Here's my answer for clock timers using both mach_absolute_time() , based on compute method shown here , and NSDate . 这是我使用基于此处所示的计算方法mach_absolute_time()NSDate时钟计时器的答案。 The are actually the same in terms of accuracy. 在准确性方面实际上是相同的。

Mach version 马赫版本

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 version 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
}

Results: 结果:

Note the resolution on both of these is really good. 请注意,这两者的分辨率都非常好。

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

*If you look at the edit history of this post, you can see the danger of using float in the place of a double ! *如果你看一下这篇文章的编辑历史,可以看到使用的危险float在的地方double

Use NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate] to get a start time, and then NSLog (@"Operation took %f seconds.", [NSDate timeIntervalSinceReferenceDate] - startTime); 使用NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate]获取开始时间,然后使用NSLog (@"Operation took %f seconds.", [NSDate timeIntervalSinceReferenceDate] - startTime); at the end. 在最后。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM