Reflexión: ¿Usar la reflexión sigue siendo "malo" o "lento"? ¿Qué ha cambiado con la reflexión desde 2002?

21

Me he dado cuenta cuando trato con Expresiones o Árboles de expresiones. Estoy usando mucho la reflexión para establecer y obtener valores en las propiedades y lo que tenemos. Se me ha ocurrido que el uso de la reflexión parece ser cada vez más común. Cosas como las anotaciones de datos para la validación, atribuir ORM pesados, etc. Me pregunto: ¿qué ha cambiado desde los días hace años y años cuando solía decirme que evitara la reflexión, si es posible?

¿Y qué, si algo ha cambiado? ¿Es solo la velocidad de las máquinas? ¿Ha habido cambios en el marco para acelerar la reflexión?

¿O realmente nada ha cambiado? ¿Sigue siendo "malo" o "lento" usar la reflexión?

carne
fuente
2
La reflexión siempre será más lenta que las llamadas directas, ya que debe realizar varios pasos para encontrar y verificar que lo que está llamando existe.
Michael K
Siempre fue malo ... Por supuesto, a veces no tienes otra opción, depende del programador saber cuándo son esos momentos y evitarlo de otra manera.
Ramhound
Realizar una Reflexión con gettype para extraer un elemento en una enumeración es aún más de 30 veces más rápido que lanzar una excepción con Enum.Parse (). Entonces la reflexión gana a veces.
Brain2000

Respuestas:

16

La reflexión no es mala ni lenta. Es simplemente una herramienta. Como todas las herramientas, es muy valioso para ciertos escenarios, no tan valioso para otros.

Si el rendimiento es realmente un problema, siempre puede usar una biblioteca como FasterFlect .

Lecturas adicionales
Si la reflexión es ineficiente, ¿cuándo es más apropiada?

Robert Harvey
fuente
O dynamic, aparentemente, un orden de magnitud más rápido que la reflexión.
Oded
1
El rendimiento no es un problema en absoluto. Solo recuerdo vívidamente a las personas que evitaban la reflexión en 2002 como si fuera la peste. Me pregunto qué ha cambiado desde entonces.
blesh
3
@blesh: nada. La gente ahora está más familiarizada con él y menos miedo.
Robert Harvey
55
Podría ser todo "salir de mi césped" aquí y decir que Lisp tenía esto mucho antes de que existiera OOP ...
Michael K
Lo suficientemente justo. Me preguntaba si fue el aumento de la velocidad en las máquinas en los últimos diez años lo que marcó la diferencia o si realmente se hicieron cambios en el sistema. Reflexión que ha impulsado el rendimiento.
carne
17

La razón por la que las personas desconfían de usar la reflexión innecesariamente no es el rendimiento: sí, hay algo de sobrecarga para usar la reflexión, pero a menudo, resolver el problema sin ella requiere un enfoque diferente con una complejidad comparable, e incluso si no lo hace, la sobrecarga es rara vez es significativo (especialmente para el desarrollo a nivel de aplicación).

Usando la reflexión, se rompen algunas suposiciones importantes que normalmente se pueden hacer sobre el código fuente, y las herramientas como "Buscar todas las referencias" dejan de funcionar de manera confiable. La reflexión también elimina básicamente la mayor parte de la seguridad de tipo que el compilador impone, por ejemplo, C #, y la mayoría de los errores de programación que un sistema de tipo normalmente detectaría y traduciría en errores del compilador, ahora se convierten en errores de tiempo de ejecución en el mejor de los casos o errores muy oscuros en el peor.

Entonces, ¿por qué la gente usa la reflexión entonces? En pocas palabras, porque a pesar de los problemas descritos anteriormente, es una herramienta muy valiosa. Con la reflexión, algunos de los beneficios de la programación dinámica se pueden obtener en un lenguaje estático, estrictamente tipado como C #, y los lenguajes de programación dinámica han demostrado sus ventajas recientemente, especialmente en el ámbito de la programación web: PHP, Javascript y Python bastante prominente. , todos usan tipeo dinámico y han demostrado ser adecuados para la programación web. Pero dado que el lenguaje sigue siendo C #, puede optar por mantener la mayor parte de su aplicación en un lenguaje estrictamente escrito de OOP, y escribir la pequeña parte donde el comportamiento dinámico realmente marca la diferencia con la reflexión.

Un ejemplo típico es cuando necesita exponer métodos como llamadas de servicio web (usando un protocolo aún no integrado en .NET). El enfoque OOP estrictamente tipificado funciona, pero es demasiado restrictivo y torpe. Pero si usa la reflexión para asignar llamadas a métodos y pares clave / valor a argumentos, puede escribir la plomería para dicho servicio web una vez y luego usarla en cualquier clase que desee.

tdammers
fuente
13

La reflexión sigue siendo significativamente más lenta que las llamadas directas. Dos cosas han cambiado:

  • Los tiempos de ejecución han optimizado los mecanismos de reflexión para que la diferencia se haya reducido.
  • Las CPU se han vuelto más rápidas para que las pequeñas ineficiencias sean más fáciles de tolerar

Juntos, estos dos factores han llevado el costo de la reflexión hasta el punto en el que puede usarlo rutinariamente (cuando sea apropiado desde un punto de vista de mantenimiento) y esperar a que el perfilador le diga si es realmente un cuello de botella (y estar razonablemente seguro de que la mayoría de el tiempo no será).

Michael Borgwardt
fuente
44
Por desgracia, las CPU se han vuelto más lentas, generalmente en dispositivos móviles y en el servidor donde las personas están tratando de exprimir la mayor eficiencia posible de sus servidores debido a los costos de ejecutarlos.
gbjbaanb
@gbjbaanb: le daré dispositivos móviles, pero en el servidor, comprar más hardware en lugar de optimizar el código es la opción aceptada y racional en la gran mayoría de los casos, porque los costos de comprar y ejecutar servidores son mucho más bajos que Los costos de optimizar el código.
Michael Borgwardt
2
En algunas situaciones, los costos del servidor superan dramáticamente los costos de desarrollo. En gran escala de estilo. Aunque los servidores son beneficiosos, el rendimiento puede ser aún más crítico que en una máquina cliente. Es un caso por caso.
Lord Tydus
1
@ Lord Tydus: claro, pero el caso que describe es la rara excepción.
Michael Borgwardt