Pregunta

Constantemente escucho lo mala 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, ¿es realmente tan malo?

¿Fue útil?

Solución

Es. Pero eso depende de lo que estés tratando de hacer.

Utilizo la reflexión para cargar ensamblajes dinámicamente (complementos) y su rendimiento " penalización " no es un problema, ya que la operación es algo que hago durante el inicio de la aplicación.

Sin embargo, si estás reflexionando dentro de una serie de bucles anidados con llamadas de reflexión en cada uno, diría que deberías revisar tu código :)

Durante " un par de veces " Operaciones, la reflexión es perfectamente aceptable y no notará ningún retraso o problema con ella. Es un mecanismo muy poderoso e incluso es usado por .NET, así que no veo por qué no debería intentarlo.

Otros consejos

En su charla El Rendimiento de las cosas cotidianas , Jeff Richter muestra que llamar a un método por reflexión es 1000 veces más lento que llamarlo normalmente.

El consejo de Jeff: si necesita llamar al método varias veces, use la reflexión una vez para encontrarlo, luego asigne un delegado y luego llame al delegado.

El rendimiento de Reflection dependerá de la implementación (las llamadas repetitivas deben almacenarse en caché, por ejemplo: entity.GetType (). GetProperty (" PropName ") ). Dado que la mayoría de la reflexión que veo en el día a día se usa para poblar entidades de lectores de datos u otras estructuras de tipo de repositorio, decidí evaluar el rendimiento específicamente en la reflexión cuando se usa para obtener o establecer propiedades de objetos.

He ideado una prueba que creo que es justa, ya que almacena en caché todas las llamadas que se repiten y solo cronometra la llamada real de SetValue o GetValue. Todo el código fuente de 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.

 Gráfica de tiempo (y) contra número de entidades pobladas (x)

El gráfico anterior muestra la salida de mi pequeño punto de referencia y muestra que los mecanismos que superan la reflexión, 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.

Si no estás en un bucle, no te preocupes por eso.

Mi experiencia más pertinente fue escribir código para comparar dos entidades de datos del mismo tipo en un gran modelo de objetos en cuanto a propiedad. Lo hice funcionar, lo probé, 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 de las 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 objeto.

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.

No masivamente. Nunca he tenido un problema con él en el desarrollo de escritorio a menos que, como dice Martin, lo estés utilizando en una ubicación tonta. He escuchado que muchas personas tienen temores irracionales sobre su desempeño en el desarrollo de computadoras de escritorio.

En el Compact Framework (en el que normalmente estoy), es bastante mucho anatema y debe evitarse como la peste en la mayoría de los casos. Todavía puedo usarlo con poca frecuencia, pero tengo que tener mucho cuidado con su aplicación, que es mucho menos divertida. :(

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: verdadero en ese momento (2008), pero hace mucho tiempo solucionado en versiones CLR más recientes. ¡Sin embargo, la reflexión en general sigue siendo algo costosa!

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 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.

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 mapas O / R en C # que usaba la reflexión para hacer los enlaces. Esto funcionó fantásticamente bien. La mayoría 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.

La reflexión puede tener un impacto notable en el rendimiento si lo usa para la creación frecuente de objetos. He desarrollado una aplicación basada en Aplicación de interfaz de usuario compuesta Bloque 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 ensamblaje, recomendaría Mono.Cecil , que es muy ligero y rápido

La reflexión es costosa debido a las muchas comprobaciones que debe realizar el tiempo de ejecución cada vez que realice una solicitud de un método que coincida con una lista de parámetros. En algún lugar en el fondo, 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 algo de código que hace cosas como verificar que pasó una lista compatible de parámetros antes de ejecutar el método de destino real.

Si es posible, siempre se recomienda que uno almacene en caché el controlador del método si va a reutilizarlo continuamente en el futuro. Como todos los buenos consejos de programación, a menudo tiene sentido evitar repetirse uno mismo. En este caso, sería inútil buscar continuamente el método con ciertos parámetros y luego ejecutarlo cada vez.

Busque en la fuente y eche un vistazo a lo que se está haciendo.

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 rellenar objetos de datarows.

Este es un escenario bastante común y hay un artículo en MSDN, Uso de Reflexión para vincular Business Objects a ASP.NET Form Controls que cubre los problemas de rendimiento.

Dejando de lado el rendimiento, una cosa que no me gusta de usar la reflexión en ese escenario en particular es que tiende a reducir la capacidad de entender el código de un vistazo rápido que para mí no vale la pena el esfuerzo cuando lo consideras también pierden el tiempo de compilación de seguridad en lugar de conjuntos de datos fuertemente tipados o algo como LINQ & nbsp; to & nbsp; SQL .

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.

Creo que encontrarás 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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top