Qué tan costoso is.NET ¿reflejo?


Escucho constantemente lo mal que se debe usar la reflexión. Aunque 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 utilizado la reflexión en aplicaciones, ¿ha medido los golpes de rendimiento y, es realmente tan malo?

Author: Peter Mortensen, 2008-08-25

13 answers

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

Utilizo reflexión para cargar dinámicamente ensamblajes (plugins) 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 reflejando dentro de una serie de bucles anidados con llamadas de reflexión en cada uno, diría que deberías volver a visitar tu código:)

Para operaciones de "un par de veces", la reflexión es perfectamente aceptable y no se dará cuenta cualquier retraso o problema con él. Es un mecanismo muy poderoso e incluso es utilizado por.NET, así que no veo por qué no deberías intentarlo.

 118
Author: Martin Marconcini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-24 23:48:33

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 reflexión una vez para encontrarlo, luego asígnelo a un delegado y luego llame al delegado.

 140
Author: ESRogs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-02 00:24:10

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

Ideé una prueba que creo que es justa ya que almacena en caché todas las llamadas repetitivas y solo multiplicado por el setValue real o Llamada 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 está devolviendo menos de 100,000 filas en un momento en que la implementación de reflexión se hace bien.

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

 54
Author: grenade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-09 15:09:24

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

 13
Author: David Plumpton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-02 01:09:39

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, luego 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 accediendo estáticamente a las propiedades. No tomó tiempo en absoluto para adaptar el código para este propósito y tuve la capacidad de hacer profundo comparación de propiedades de entidades con código estático que podría actualizarse con el clic de 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 para generar automáticamente código para compilar en lugar de realizar operaciones de tiempo de ejecución y esto a menudo vale la pena considerar.

 12
Author: Gaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-31 12:18:42

No masivamente. Nunca he tenido un problema con él en el desarrollo de escritorio a menos que, como dice Martin, lo estés usando en una ubicación tonta. He oído que mucha gente tiene temores totalmente irracionales sobre su rendimiento en el desarrollo de escritorio.

En el Marco compacto (en el que suelo estar), sin embargo, es bastante anatema y debe evitarse como la plaga en la mayoría de los casos. Todavía puedo salirme con la suya con poca frecuencia, pero tengo que tener mucho cuidado con su aplicación que es mucho menos divertido. :(

 12
Author: Quibblesome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-08 16:59:39

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 el momento (2008), pero hace mucho tiempo arreglado en versiones más recientes de CLR. Sin embargo, la reflexión en general sigue siendo algo costoso.

Ejemplo: Nunca debe usar un miembro declarado como "Objeto" en un lock (C#) / SyncLock ( VB.NET) declaración en código de alto rendimiento. ¿Por qué? Porque el CLR no puede bloquear un tipo de valor, lo que significa que tiene que hacer una comprobación de 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.

 9
Author: McKenzieG1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-05 16:39:25

Al igual que 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. He creado una biblioteca de asignación de O/R en C# que utiliza la reflexión para hacer los enlaces. Esto funcionó fantásticamente bien. La mayor parte del código de reflexión solo se ejecutaba una vez, por lo que cualquier impacto en el rendimiento era bastante pequeño, pero los beneficios eran grandes. Si estuviera escribiendo un nuevo algoritmo de clasificación fandangled, probablemente no usaría reflexión, ya que probablemente escalaría mal.

Aprecio que no haya respondido exactamente a su pregunta aquí. Mi punto es que realmente no importa. Utilice la reflexión cuando corresponda. Es solo otra característica de idioma que necesita aprender cómo y cuándo usar.

 5
Author: Mike Thompson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-25 00:04:13

La reflexión puede tener un impacto notable en el rendimiento si se utiliza para la creación frecuente de objetos. He desarrollado una aplicación basada en Composite UI Application Block que depende en gran medida 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, le recomendaría Mono.Cecil que es muy ligero y rápido

 3
Author: aku,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-25 00:01:54

La reflexión es costosa debido a las muchas comprobaciones que debe realizar el tiempo de ejecución cada vez que realiza una solicitud para un método que coincida con una lista de parámetros. En algún lugar profundo, existe código que recorre todos los métodos para un tipo, verifica su visibilidad, comprueba el tipo de retorno y también comprueba el tipo de todos y cada uno de los parámetros. Todo esto cuesta tiempo.

Cuando ejecutas ese método internamente hay algún código que hace cosas como verificar que pasaste 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 método handle 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.

Hurgue alrededor de la fuente y eche un vistazo a lo que se está haciendo.

 3
Author: mP.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-25 05:41:49

Como con todo, se trata de evaluar la situación. En DotNetNuke hay un componente bastante central llamado FillObject que usa la reflexión para rellenar objetos desde datarows.

Este es un escenario bastante común y hay un artículo sobre MSDN, Usar la Reflexión para Enlazar Objetos de Negocio a ASP.NET Controles de Formulario eso 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 parece que valga la pena el esfuerzo cuando se considera que también se pierde la seguridad del tiempo de compilación en lugar de conjuntos de datos fuertemente escritos o algo así como LINQ a SQL.

 3
Author: lomaxx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-22 09:51:56

La reflexión no ralentiza drásticamente el rendimiento de tu app. Es posible que pueda hacer ciertas cosas más rápido al no usar reflexión, pero si la reflexión es la forma más fácil de lograr alguna funcionalidad, utilícela. Siempre puede refactorizar su código lejos de la Reflexión si se convierte en un problema de perf.

 2
Author: Chris Pietschmann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-15 22:03:15

Creo que encontrarás que la respuesta es, depende. No es un gran problema si desea ponerlo en su aplicación de lista de tareas. Es un gran problema si quieres ponerlo en la biblioteca de persistencia de Facebook.

 1
Author: Travis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-22 10:01:01