Cuando lo piense bien, la reflexión es bastante impresionante en qué tan rápido es.
Se puede llamar a un delegado en caché de ConstructorInfo
o MethodInfo
con una velocidad comparable a la de cualquier otro delegado.
Un delegado creado a partir de ILGenerator.Emit
(que, por cierto, no es nuevo, ha estado en .NET desde la versión 1) también se puede llamar igual de rápido.
Un objeto obtenido al emitir o llamar a un delegado ConstructorInfo
será tan rápido como cualquier otro objeto.
Si obtiene un objeto cargando un ensamblaje dinámicamente, usando la reflexión para encontrar el método para llamar y llamarlo, e implementa una interfaz definida a través de la cual lo llama a partir de ese punto, entonces será simplemente tan rápido como se usa como otra implementación de esa interfaz.
En total, la reflexión nos da formas de hacer las cosas que sin ella, si pudiéramos hacerlas, tendremos que usar técnicas que son más lentas tanto para codificar como para ejecutar.
También nos ofrece medios para hacer cosas que son más complicadas, más quebradizas, menos seguras y menos efectivas que otros medios también. Casi todas las líneas del código C# pueden ser reemplazadas por una gran porción de código que utiliza la reflexión. Es casi seguro que este código será peor que la línea original en muchos aspectos, y el rendimiento es el menor de ellos.
Posiblemente el consejo de "evitar la reflexión porque es lento" parte de la creencia de que el tipo de desarrollador que se volvería loco por cualquier técnica nueva simplemente porque parecía genial sería del tipo que probablemente sería advertido por " será más lento "que por" será menos idiomático, más propenso a errores y más difícil de mantener ". Muy posiblemente esta creencia es completamente correcta.
En su mayor parte, cuando el enfoque más natural y obvio es utilizar la reflexión, entonces tampoco será menos eficaz que un intento realmente complicado para evitarlo.
Si los problemas de rendimiento se aplican a cualquier cosa en la reflexión, es realmente a los usos que se ocultan:
Usando dynamic
puede parecer razonable en un caso en el que sólo un poco de trabajo podría evitarlo. Aquí vale la pena considerar la diferencia de rendimiento.
En ASP.NET, usar <%#DataBinder.Eval(Container.DataItem, "SomeProperty")%>
es más fácil pero generalmente menos eficiente que <#((SomeType)Container.DataItem).SomeProperty%>
o <%#SomeCodeBehindProvidedCallWithTheSameResult%>
. Seguiré usando el anterior 90% del tiempo, y el último solo si realmente me importa el rendimiento de una página dada o más probablemente porque hacer muchas operaciones en el mismo objeto hace que este último sea más natural.
De modo que, en general, todo permanece "lento" en las computadoras mientras que están limitadas por el requisito de trabajar en un solo universo de una manera que consume energía y toma tiempo, por algún valor de "lento". Las diferentes técnicas de reflexión tienen costos diferentes, pero también lo hacen las alternativas. Tenga cuidado no tanto de la reflexión en los casos en que es el enfoque obvio como la reflexión oculta donde otro enfoque un poco menos obvio puede servir bien.
Y por supuesto, codifique sabiamente con cualquier técnica que use. Si va a llamar al mismo delegado cien veces seguidas, debe almacenarlo en lugar de obtenerlo en cada llamada, y eso sería si la forma de obtenerlo era a través de la reflexión o no.
"¿La reflexión es realmente lenta?" - ¿comparado con que? –
+1, aunque no ejecutó los números usted mismo. Siempre he escuchado esto, sin embargo, [no puedo pensar dónde] (http://xkcd.com/125/). Aún así, nunca me impidió usar el reflejo, que nunca he encontrado lento. Según los rumores, es contradictorio, al menos cuando el código refleja el ensamblaje cargado (como suele ser el caso): si hay una cosa que usted sabe que está cargada en la memoria, ¡es el ensamble que ejecuta el código! Debería ser rápido como cualquier otra cosa. – harpo
var x = new Ejemplo(); vs Activator.CreateInstance ("...."); – adt