2009-05-25 9 views
5

Tengo curiosidad por saber el costo del envío de mensajes en Objective-C en diversas situaciones. Particularmente, quiero guiar mi elección del diseño del programa, por lo que no me siento tentado a optimizar prematuramente al evitar el envío de mensajes cuando se trata de un mejor diseño.Costo del envío de mensajes en Objective-C

Un caso en mi proyecto actual es que tengo una clase con variables de instancia: offsetX y offsetY. A menudo quieren compensar el absoluto y por el momento no tengo esta línea de código por todo el lugar: -

int absOffset = ((offsetX < 0.0) ? -offsetX : offsetX) + 
       ((offsetY < 0.0) ? -offsetY : offsetY); 

Ahora bien, si esto era C++ crearía una función en línea que devuelve el valor de absOffset. Incluso en Java/C# podría definir una función como final/sellada y estar bastante seguro de que estaría en línea.

El objetivo-C sería la siguiente: -

-(int)absOffset { 
    return ((offsetX < 0.0) ? -offsetX : offsetX) + 
      ((offsetY < 0.0) ? -offsetY : offsetY); 
} 

y yo lo llamaría así: -

int ao = [self absOffset]; 

Ahora, es el compilador capaz de línea que? Supongo que es capaz, al menos, de corregirlo en una llamada a función directa y evitar el envío de mensajes dinámicos que (supongo) objetivo-c debe usar debido a su tipo de sistema.

Además, en general, ¿cuánto cuesta el envío de mensajes en el objetivo C? ¿Difiere al llamar a través de un 'id' frente a un puntero a una clase concreta?

Respuesta

14

Objective C messages are very fast. La velocidad es comparable a las llamadas a métodos virtuales en C++, aunque no tan rápido. Evitar la transmisión de mensajes es definitivamente optimización prematura. Puede que no quieras hacer mucho en un bucle interno, pero los algoritmos que elijas y otros factores tendrán un factor mucho más grande en la rapidez de tu código. Si es demasiado lento, use un generador de perfiles y vaya desde allí.

+6

+1. Vale la pena señalar que el código de mensajería está escrito en un código ensamblador altamente optimizado, que se encuentra aquí: http://opensource.apple.com/source/objc4/objc4-371.2/runtime/Messengers.subproj/ –

+1

I ' Me estoy rascando la cabeza ante los números de Mike Ash por los costos operativos. Ejecuté una medición similar de sobrecarga de llamada virtual en C++, y el tiempo que obtuve para cada indirecto virtual en un procesador de 3.3GHz fue más como 7ns que su 1. – Crashworks

+4

Según el enlace publicado, una llamada a función virtual requiere 1.1ns mientras que un objetivo- El envío de C tarda 4.9ns, que es casi 5 veces más lento. Tan rápido como el despachador se supone que puede ser un éxito en las circunstancias correctas. ¡Definitivamente estoy de acuerdo en evitar una optimización prematura! – fbrereto

5

Primero, usaría la función C, fabs() para esto. Para otras cosas, escribir funciones simples, en línea, C para pequeños casos auxiliares puede funcionar bien. Usar métodos de conveniencia más que un comportamiento discreto puede ser un signo de mal diseño. El rendimiento ni siquiera llega a eso.

A continuación, el compilador no puede optimizar una llamada de método. Es un lenguaje dinámico, la llamada no se resuelve hasta el tiempo de ejecución. Varias técnicas de Objective-C podrían vencer cualquier intento del compilador de hacerlo.

No hay diferencia en el tiempo de ejecución entre llamar a un método en un "id" frente a un puntero tipeado: pasan exactamente por el mismo mecanismo.

Finalmente, si está pensando en las características de rendimiento antes de medir, ya está optimizando prematuramente. Eso no quiere decir que es nunca apropiado, como algunos pueden hacer creer, pero por lo general es cierto. En este caso, creo que si pones el diseño primero, probablemente termines con un perfil de rendimiento lo suficientemente bueno. Mida y optimice más tarde, según sea necesario.

+0

¿Podría abordar algunas técnicas para reducir el costo del mecanismo de mensajes (envío dinámico) en Objective-C? – Eonil

+1

No hay mucho que pueda hacer para reducir su costo, per se. Es un mecanismo fijo, y ya está bastante bien optimizado. Hay cosas a tener en cuenta, sin embargo, como no usar métodos cuando las funciones de ayuda de C son más apropiadas (según mi post anterior), evitar el boxeo y el desempaquetado donde se pueda, y solo buenos principios generales de diseño. Si el costo del envío de mensajes es realmente un cuello de botella (se sugiere que muy raramente lo es), entonces tal vez Obj-C no sea la herramienta adecuada. Puede mezclar C++ con Objective-C (Objective-C++) con bastante facilidad, por ejemplo. – philsquared

+0

+1 por "El uso de métodos de conveniencia en lugar de un comportamiento discreto puede ser un signo de mal diseño. El rendimiento ni siquiera llega a él". ¡Exactamente! –

Cuestiones relacionadas