Código de Timing Objective-C.
-
06-07-2019 - |
Pergunta
Gostaria de adicionar algum teste de desempenho automatizado ao meu aplicativo Objective-C. (Este é um jogo, para que eu gostaria de ver o desempenho atual das partes importantes do motor, simplesmente executando um conjunto de testes.) Para fazer isso, quero escrever alguma rotina de suporte de tempo, algo assim:
- (void) benchmarkSelector: (SEL) msg onObject: (id) target
{
// run the selector thousands of times, print detailed stats
}
O problema é que estou interessado em milissegundos e receio que chamasse performSelector
No código de benchmarking, distorceria bastante os resultados. Como você daria contornar isso? Devo descer para objc_msgSend
?
Solução
Usar methodForSelector:
, que retorna um ponteiro de função para a implementação real, assim:
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
}
Observe que essa estratégia é útil para medir o tempo de execução real de um método, mas se você estiver chamando com a sintaxe de passagem de mensagem Objective-C padrão, pode ser igualmente relevante incluir a sobrecarga que passa de mensagem em suas medidas.
Além disso, observe que, se o método realmente leva outros parâmetros, você deve lançar o resultado de methodForSelector:
para um ponteiro de função com os parâmetros apropriados, para evitar conversão inesperada de carros alegóricos em duplas, etc. Veja o Referência de classe NSObject Para mais informações e exemplos.