2009-06-23 6 views
8

Me gustaría agregar algunas pruebas de rendimiento automáticas a mi aplicación Objective-C. (Este es un juego, por lo que me gustaría ver el rendimiento actual de las partes clave del motor simplemente ejecutando un conjunto de pruebas). Para hacer esto, quiero escribir alguna rutina de soporte de tiempo, algo como esto:Timing Objective-C código

- (void) benchmarkSelector: (SEL) msg onObject: (id) target 
{ 
    // run the selector thousands of times, print detailed stats 
} 

El problema es que estoy interesado en milisegundos y me temo que llamar al performSelector en el código de referencia sesgaría un poco los resultados. ¿Cómo irías por esto? ¿Debo bajar al objc_msgSend?

+0

¿este es el código específico de Cocoa? – Nippysaurus

+0

No estoy seguro, probablemente no. – zoul

Respuesta

12

Uso methodForSelector:, que devuelve un puntero de función a la aplicación efectiva, así:

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 
} 

Tenga en cuenta que esta estrategia es útil para medir el tiempo de ejecución real de un método, pero si vas a estar llamándolo con la sintaxis estándar de paso de mensajes de Objective-C, entonces podría ser tan relevante incluir la sobrecarga de transmisión de mensajes en sus mediciones.

Además, tenga en cuenta que si el método realmente tiene cualquier otro parámetro, debe emitir el resultado de methodForSelector: a un puntero de función con los parámetros adecuados, para evitar la conversión inesperada de flotadores a los dobles, etc. Ver la NSObject Class Reference para más información y ejemplos.

+0

Tiene razón acerca de incluir la sobrecarga de transmisión de mensajes, pero me preocupaba que el performSelector: podría tomar 'mucho' más tiempo que simplemente enviar el mensaje. Después de escribir el código, no se ve tan mal, y si quisiera, siempre podría regresar al IMP. Gracias. – zoul

+0

¿No obtendría mejores resultados si usó uint64_t start = mach_absolute_time(); uint64_t duration = mach_absolute_time() - start; que le da nanosegundos en lugar de segundos? – micmoo

+2

NSTimeInterval es un doble. El resultado se expresa en términos de segundos, pero tiene una precisión de menos de milisegundos. Como OP está buscando milisegundos, creo que es lo suficientemente bueno. Pero sí, mach_absolute_time() también funcionaría. –

Cuestiones relacionadas