2010-08-17 12 views
21

¿Es porque deberíamos cargar la clase (por ejemplo, string), crear una instancia, luego buscar el método apropiado, los parámetros del paquete y luego simplemente invocar el método? Entonces, la mayor parte del tiempo se gasta en estas operaciones en lugar de la invocación explícita de métodos en un objeto, ¿verdad?¿Por qué la reflexión es lenta?

+3

En la implementación moderna de jdk/jvm no es tan lento como crees. – Roman

Respuesta

28

Cada paso que toma necesita ser validado cada vez que lo toma cuando utiliza la reflexión. Por ejemplo, cuando invoca un método, necesita verificar si el objetivo es realmente una instancia del declarante del método, si tiene el número correcto de argumentos, si cada argumento es del tipo correcto, etc.

No hay absolutamente ninguna posibilidad de realizar incrustaciones u otros trucos de rendimiento.

Si encuentra tipos o métodos por nombre, en el mejor de los casos implicará una simple búsqueda de mapas, que se realizará cada vez que la ejecute, en lugar de una vez en el tiempo JIT.

Básicamente hay mucho más por hacer. Sin embargo, la reflexión se ha vuelto mucho más rápida de lo que solía ser ... si lo encuentras demasiado lento, es muy posible que lo estés usando en exceso.

+1

Otro sutil problema es que cuando se utiliza la reflexión, los ofuscadores pueden necesitar ser menos agresivos, lo que da como resultado menos beneficios.(Muchos fabricantes de ofuscación afirman que la ofuscación ofrece beneficios de rendimiento, así como protección de IP y reducción de huella. Véase, por ejemplo, [este artículo] (http://www.devx.com/wireless/Article/28989/1954).) –

+0

Es solo las invocaciones son especialmente lentas? ¿Qué ocurre con otros usos de reflexión como enumerar propiedades, obtener el tipo de declaración, obtener métodos getter/setter, etc.? ¿Son estos lentos también? –

+0

@zespri: Bueno, "lento" suele ser relativo a otra cosa: es difícil decir si enumerar propiedades es "lento" porque eso no es algo que se hace fuera de la reflexión, mientras que "invocar método" o "obtener valor de campo" es mucho más lento con la reflexión que directamente. Si las operaciones de solo reflexión son más lentas de lo que su aplicación necesita, es una cuestión diferente ... –

6

Como una adición a la respuesta de Jon Skeet anterior (necesito más renombre con el fin de poder hacer comentarios.):

La reflexión es dependiente de los recursos de CPU disponibles; si tiene problemas con su aplicación que es lenta, la reflexión no resolverá nada, simplemente hágalo más lento.

Al igual que Java en sí, la reflexión no se tarda más - que es más de un viejo rumor;)

+0

La reflexión no es lenta, no es verdad. Un toString() para tres clases vaables, es un cincuenta por ciento más lento para mí que el codificado a mano en String. (Estoy usando OpenJDK 8) –

2

Cuando se llama a un método, lo que necesita saber si está haciendo lo mismo con argumentos válidos, en un objeto válido, cuál es el tipo de devolución y qué bytecode ejecutar. Cuando el método exacto se especifica en el código, Java puede resolver rápidamente este problema y pasar a la ejecución real del método.

Cuando haces esto con la reflexión, sabes mucho menos. Dado que el método que se invocó no se especificó en el código, nada de esto se puede hacer de antemano, y la máquina virtual tiene que hacer cosas en tiempo de ejecución que son mucho más complejas y requieren mucho procesamiento.

Las llamadas a métodos polimórficos se pueden considerar como algo entre estos dos extremos. No sabe qué método invocar hasta el tiempo de ejecución, pero al menos puede estar seguro del nombre, los argumentos y el tipo de devolución del método. Cuanto más sepa sobre qué método ejecutar, más puede evitar hacerlo en tiempo de ejecución.

Esto demuestra que la reflexión es más lenta, pero no es que sea realmente "lenta". Si necesita métodos de reflexión o polimórficos, úselos y guarde el juicio de lo que es "lento" para más adelante.

0

Si lo usa de forma adecuada, no es tan lento. Por ejemplo, lo usé para escanear toda la propiedad de la clase de modelo, estaba funcionando perfectamente.

En otros casos, como comprobar si el destino tiene el mismo tipo o firma, es absolutamente lento.

Evento es algo lento, pero es importante para la implementación de fábrica ...: D.

Cuestiones relacionadas