timeIntervalSinceDate Точность - PullRequest
       11

timeIntervalSinceDate Точность

0 голосов
/ 25 декабря 2010

Я работаю над игрой с движком, который обновляется 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,000012 мс, но события меньшего размера заняли всего 0,000001 мс. Так что же случилось с остальными 0,000011 мс?

Есть ли что-то, что выглядит особенно неправильно с моим кодом? Или я должен использовать альтернативный механизм синхронизации?

1 Ответ

1 голос
/ 25 декабря 2010

Ну, есть время, необходимое для запуска [NSDate date] и [endTime timeIntervalSinceDate:startDate], что, вероятно, объясняет разницу.

Однако я бы использовал CACurrentMediaTime(), который возвращает CFTimeInterval (чтоdouble), или mach_absolute_time(), который возвращает длинное целое без знака.Оба они избегают создания объектов и, вероятно, занимают меньше времени.

Конечно, вы все равно будете вычитать два числа в каждом кадре, что занимает время.Мое предложение обойти это было бы просто использовать 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;
}

Это учитывает время, затраченное на конец одного кадра до конца следующего, включая время, необходимое для вычитания ивызовы метода.

...