Временной код Objective-C
-
06-07-2019 - |
Вопрос
Я хотел бы добавить несколько автоматизированных тестов производительности в свое приложение Objective-C.(Это игра, так что я хотел бы увидеть текущую производительность ключевых частей движка, просто запустив набор тестов.) Для этого я хочу написать некоторую процедуру поддержки синхронизации, что-то вроде этого:
- (void) benchmarkSelector: (SEL) msg onObject: (id) target
{
// run the selector thousands of times, print detailed stats
}
Проблема в том, что меня интересуют миллисекунды, и я боюсь, что вызов performSelector
в коде бенчмаркинга результаты были бы немного искажены.Как бы вы обошли это?Должен ли я спуститься в objc_msgSend
?
Решение
Использование methodForSelector:
, который возвращает указатель функции на фактическую реализацию, например:
IMP methodImp = [target methodForSelector:msg];
for (int i=0; i<1000; ++i) {
NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];
methodImp(target, msg);
NSTimeInterval duration = [NSDate timeIntervalSinceReferenceDate] - start;
// Do something with duration
}
Обратите внимание, что эта стратегия полезна для измерения фактического времени выполнения метода, но если вы собираетесь вызывать его со стандартным синтаксисом передачи сообщений Objective-C, то может оказаться столь же уместным включить служебные данные для передачи сообщений в ваши измерения.
Также обратите внимание, что если метод действительно принимает какие-либо другие параметры, вы должны привести результат methodForSelector:
к указателю на функцию с соответствующими параметрами, чтобы избежать неожиданного преобразования значений с плавающей запятой в двойные и т.д.Посмотрите на Ссылка на класс NSObject для получения дополнительной информации и примеров.