Constantemente escucho lo mal que es usar la reflexión. Si bien generalmente evito la reflexión y rara vez encuentro situaciones en las que es imposible resolver mi problema sin ella, me preguntaba ...
Para aquellos que han usado la reflexión en aplicaciones, ¿han medido los éxitos de rendimiento y, realmente, es tan malo?
c#
.net
performance
reflection
Dan Herbert
fuente
fuente
Respuestas:
Es. Pero eso depende de lo que intentes hacer.
Utilizo la reflexión para cargar dinámicamente ensamblajes (complementos) y su "penalización" de rendimiento no es un problema, ya que la operación es algo que hago durante el inicio de la aplicación.
Sin embargo, si está reflejando dentro de una serie de bucles anidados con llamadas de reflexión en cada uno, le diría que debería volver a visitar su código :)
Para operaciones de "un par de veces", la reflexión es perfectamente aceptable y no notará ningún retraso o problema con ella. Es un mecanismo muy poderoso e incluso es utilizado por .NET, así que no veo por qué no deberías intentarlo.
fuente
En su charla The Performance of Everyday Things , Jeff Richter muestra que llamar a un método por reflexión es aproximadamente 1000 veces más lento que llamarlo normalmente.
Consejo de Jeff: si necesita llamar al método varias veces, use la reflexión una vez para encontrarlo, luego asígnelo a un delegado y luego llame al delegado.
fuente
El rendimiento de la reflexión dependerá de la implementación (las llamadas repetitivas deben almacenarse en caché, por ejemplo:)
entity.GetType().GetProperty("PropName")
. Como la mayor parte de la reflexión que veo a diario se usa para llenar entidades de lectores de datos u otras estructuras de tipo de repositorio, decidí comparar el rendimiento específicamente en la reflexión cuando se usa para obtener o establecer propiedades de un objeto.Diseñé una prueba que creo que es justa, ya que almacena en caché todas las llamadas repetidas y solo veces la llamada real de SetValue o GetValue. Todo el código fuente para la prueba de rendimiento está en bitbucket en: https://bitbucket.org/grenade/accessortest . El escrutinio es bienvenido y alentado.
La conclusión a la que he llegado es que no es práctico y no proporciona mejoras de rendimiento notables para eliminar la reflexión en una capa de acceso a datos que devuelve menos de 100,000 filas en un momento en que la implementación de la reflexión se realiza correctamente.
El gráfico anterior muestra el resultado de mi pequeño punto de referencia y muestra que los mecanismos que superan el reflejo, solo lo hacen notablemente después de la marca de 100,000 ciclos. La mayoría de los DAL solo devuelven varios cientos o quizás miles de filas a la vez y en estos niveles la reflexión funciona bien.
fuente
Si no estás en un bucle, no te preocupes por eso.
fuente
Mi experiencia más pertinente fue escribir código para comparar dos entidades de datos del mismo tipo en un modelo de objeto grande en cuanto a propiedades. Lo hice funcionar, lo intenté, corrí como un perro, obviamente.
Estaba abatido, y de la noche a la mañana me di cuenta de que sin cambiar la lógica, podría usar el mismo algoritmo para generar automáticamente métodos para hacer la comparación pero acceder estáticamente a las propiedades. No me llevó mucho tiempo adaptar el código para este propósito y tuve la capacidad de hacer una comparación profunda de las propiedades con entidades con código estático que podría actualizarse con solo hacer clic en un botón cada vez que cambiara el modelo de objetos.
Mi punto es: en conversaciones con colegas, ya que he señalado varias veces que su uso de la reflexión podría ser autogenerar código para compilar en lugar de realizar operaciones de tiempo de ejecución y esto a menudo vale la pena considerarlo.
fuente
No masivamente Nunca he tenido un problema con él en el desarrollo de escritorio a menos que, como dice Martin, lo esté usando en una ubicación tonta. He oído que mucha gente tiene miedos completamente irracionales sobre su desempeño en el desarrollo de escritorio.
Sin embargo, en el Marco Compacto (en el que generalmente estoy), es prácticamente anatema y debe evitarse como la peste en la mayoría de los casos. Todavía puedo evitar usarlo con poca frecuencia, pero tengo que tener mucho cuidado con su aplicación, que es mucho menos divertida. :(
fuente
Ya es bastante malo que tenga que preocuparse incluso por la reflexión realizada internamente por las bibliotecas .NET para el código crítico de rendimiento.
El siguiente ejemplo es obsoleto, cierto en ese momento (2008), pero hace mucho tiempo corregido en versiones CLR más recientes. Sin embargo, la reflexión en general sigue siendo algo costoso.
Caso en cuestión: nunca debe usar un miembro declarado como "Objeto" en una declaración de bloqueo (C #) / SyncLock (VB.NET) en código de alto rendimiento. ¿Por qué? Debido a que el CLR no puede bloquear un tipo de valor, lo que significa que tiene que hacer una verificación del tipo de reflexión en tiempo de ejecución para ver si su objeto es realmente un tipo de valor en lugar de un tipo de referencia.
fuente
Como con todas las cosas en la programación, debe equilibrar el costo de rendimiento con cualquier beneficio obtenido. La reflexión es una herramienta invaluable cuando se usa con cuidado. Creé una biblioteca de mapeo O / R en C # que usaba la reflexión para hacer los enlaces. Esto funcionó fantásticamente bien. La mayor parte del código de reflexión solo se ejecutó una vez, por lo que cualquier impacto en el rendimiento fue bastante pequeño, pero los beneficios fueron excelentes. Si estuviera escribiendo un nuevo algoritmo de clasificación enredado, probablemente no usaría la reflexión, ya que probablemente escalaría mal.
Aprecio que no haya respondido exactamente su pregunta aquí. Mi punto es que realmente no importa. Use la reflexión donde sea apropiado. Es solo otra característica del idioma que necesita para aprender cómo y cuándo usarla.
fuente
La reflexión puede tener un impacto notable en el rendimiento si la usa para la creación frecuente de objetos. Desarrollé una aplicación basada en el Bloque de aplicaciones de IU compuesto, que depende mucho de la reflexión. Hubo una notable degradación del rendimiento relacionada con la creación de objetos a través de la reflexión.
Sin embargo, en la mayoría de los casos no hay problemas con el uso de la reflexión. Si su única necesidad es inspeccionar algún conjunto, le recomendaría Mono.Cecil, que es muy ligero y rápido.
fuente
La reflexión es costosa debido a las muchas comprobaciones que debe hacer el tiempo de ejecución cada vez que realiza una solicitud de un método que coincida con una lista de parámetros. En algún lugar profundo, existe un código que recorre todos los métodos para un tipo, verifica su visibilidad, verifica el tipo de retorno y también verifica el tipo de cada parámetro. Todo esto cuesta tiempo.
Cuando ejecuta ese método internamente, hay algún código que hace cosas como verificar que haya pasado una lista compatible de parámetros antes de ejecutar el método de destino real.
Si es posible, siempre se recomienda que se almacene en caché el identificador de método si se va a reutilizar continuamente en el futuro. Como todos los buenos consejos de programación, a menudo tiene sentido evitar repetirse. En este caso, sería un desperdicio buscar continuamente el método con ciertos parámetros y luego ejecutarlo cada vez.
Examine la fuente y eche un vistazo a lo que se está haciendo.
fuente
Como con todo, se trata de evaluar la situación. En DotNetNuke hay un componente bastante básico llamado
FillObject
que usa la reflexión para poblar objetos desde datarows.Este es un escenario bastante común y hay un artículo sobre MSDN, Uso de Reflection para vincular Business Objects a ASP.NET Form Controls que cubre los problemas de rendimiento.
Rendimiento aparte, una cosa que no me gusta de usar la reflexión en ese escenario particular es que tiende a reducir la capacidad de entender el código de un vistazo rápido, lo que para mí no parece que valga la pena cuando consideras que también pierdes compilación seguridad de tiempo en lugar de conjuntos de datos fuertemente tipados o algo así como LINQ to SQL .
fuente
Reflection no reduce drásticamente el rendimiento de su aplicación. Es posible que pueda hacer ciertas cosas más rápido al no usar la reflexión, pero si la reflexión es la forma más fácil de lograr alguna funcionalidad, entonces úsela. Siempre puede refactorizar su código lejos de Reflection si se convierte en un problema de rendimiento.
fuente
Creo que encontrará que la respuesta es, depende. No es gran cosa si quieres ponerlo en tu aplicación de lista de tareas. Es un gran problema si quieres ponerlo en la biblioteca de persistencia de Facebook.
fuente