Вопрос

Я хотел бы добавить несколько автоматизированных тестов производительности в свое приложение 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 для получения дополнительной информации и примеров.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top