timeIntervalSinceDate准确性

时间:2010-12-25 18:08:09

标签: iphone objective-c nsdate nstimeinterval

我一直在开发一款每秒更新20次的引擎。我现在必须指出我想要开始获得一些性能数据并调整渲染和逻辑更新。为了做到这一点,我开始在我的游戏循环中添加一些计时代码,实现如下......

NSDate* startTime = [NSDate date];
// Game update logic here....
// Also timing of smaller internal events
NSDate* endTime = [NSDate date];
[endTime timeIntervalSinceDate:startTime];

但是我注意到,当我在外部时序逻辑中对时间块进行计时时,他们执行的时间并没有达到与总时间相匹配的程度。

所以我写了一个小单元测试来演示问题,我在这个问题上花费了完成测试所需的总时间,然后是10个较小的事件,这里是......

- (void)testThatSumOfTimingsMatchesOverallTiming {

NSDate* startOfOverallTime = [NSDate date];

// Variable to hold summation of smaller timing events in the upcoming loop...
float sumOfIndividualTimes = 0.0;
NSTimeInterval times[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
for (int i = 0; i < 10; i++) {
    NSDate* startOfIndividualTime = [NSDate date];
    // Kill some time...
    sleep(1);
    NSDate* endOfIndividualTime = [NSDate date];
    times[i] = [endOfIndividualTime timeIntervalSinceDate:startOfIndividualTime];
    sumOfIndividualTimes += times[i];
}

NSDate* endOfOverallTime = [NSDate date];
NSTimeInterval overallTimeTaken = [endOfOverallTime timeIntervalSinceDate:startOfOverallTime];

NSLog(@"Sum of individual times: %fms", sumOfIndividualTimes);
NSLog(@"Overall time: %fms", overallTimeTaken);

STAssertFalse(TRUE, @"");
}

这是输出......

Sum of individual times: 10.001377ms
Overall time: 10.016834ms

这清楚地说明了我的问题。总时间为0.000012ms,但较小的事件仅花费0.000001ms。那么其他0.000011ms发生了什么?

我的代码有什么特别错的吗?或者我应该使用另一种计时机制吗?

1 个答案:

答案 0 :(得分:1)

嗯,运行[NSDate date][endTime timeIntervalSinceDate:startDate]需要一些时间来解决差异。

但是,我会使用CACurrentMediaTime()返回一个CFTimeInterval(只是一个双精度),或mach_absolute_time()返回一个unsigned long int。这两个都可以避免创建对象,并且可能花费更少的时间。

当然,你仍然会每帧减去两个数字,这需要时间。我建议解决这个问题就是使用lastFrameEnd:

CFTimeInterval lastFrameEnd = CACurrentMediaTime();
while (true) {
  // Game update logic here....
  // Also timing of smaller internal events
  CFTimeInterval frameEnd = CACurrentMediaTime();
  CFTimeInterval duration = frameEnd - lastFrameEnd;  //Use this
  lastFrameEnd = frameEnd;
}

这考虑了一帧结束到下一帧结束所花费的时间,包括减法和方法调用所花费的时间。