Вы заметили, что dispatch_after работает на 10% медленнее на устройствах iOS?

В последнее время яя использовал dispatch_after вместо executeSelector: withObject: afterDelay, когда я хочу вызвать некоторый код после задержки. Код чище, у него есть доступ к закрытой области видимости, я могу поместить код в строку вместо написания одноразового метода и т. Д. И т. Д.

Мой код может выглядеть так:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
  delay * NSEC_PER_SEC),
  dispatch_get_main_queue(),
  ^{
    //Delayed-execution code goes here.
  }
);

Однако недавно я обнаружил, что время выполнения этого кода, по-видимому, работает примерно на 10% медленнее, чем запрошено. Если я запрашиваю задержку в 10 секунд, мой блок исполняется примерно через 11 секунд. Это на устройстве iOS. Кажется, что времена на симуляторе совпадают.

Код яЯ использую, чтобы проверить это довольно просто: я

NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
  delay * NSEC_PER_SEC),
  dispatch_get_main_queue(),
  ^{
    NSTimeInterval actualDelay = [NSDate timeIntervalSinceReferenceDate] - startTime;
    NSLog(@"Requested delay = %.3f. Atual delay = %.3f", delay, actualDelay);
    //Delayed-execution code goes here.
  }
);

Мы тестировали на устройствах от iOS 4S до iPad Air, и дополнительная задержка довольно стабильна. У меня нетЯ пока не тестировал его на более старых устройствах, таких как iPhone 4 или iPad 2, хотя скоро я это сделаю.

Я мог бы ожидать 20-50 мсотстойные» в задержке, но постоянное превышение на 10% - 11% является странным.

мы добавили "фактор выдумки " на мой код, который корректирует дополнительную задержку, но я нахожу это удивительным:

#define  delay_fudge 0.912557 //Value calculated based on averages from testing.


NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
  delay * delay_fudge *  NSEC_PER_SEC),
  dispatch_get_main_queue(),
  ^{
    NSTimeInterval actualDelay = [NSDate timeIntervalSinceReferenceDate] - startTime;
    NSLog(@"Requested delay = %.3f. Actual delay = %.3f", delay, actualDelay);
    //Delayed-execution code goes here.
  }
);

Я, вероятно, должен сделать больше анализа и посмотреть, есть ли фиксированное увеличение задержки плюс коэффициент задержки или прямая процентная задержка, или, возможно, некоторая нелинейная шкала ошибки, но сейчас простой множитель, кажется, работает довольно хорошо.

Ответы на вопрос(1)

Ваш ответ на вопрос