2008-10-22 16 views
64

Duplicar posibles:
How costly is .NET reflection?¿Cuál es el "costo" de la reflexión .NET?

Actualmente estoy en una mentalidad de programación que la reflexión es mi mejor amigo. Lo uso mucho para la carga dinámica de contenido que permite una "implementación flexible" en lugar de interfaces estrictas, así como una gran cantidad de atributos personalizados.

¿Cuál es el costo "real" del uso de la reflexión?

¿Vale la pena el esfuerzo de los tipos reflejados con frecuencia para tener reflejos en caché, como nuestro propio código de objeto DAL pre-LINQ en todas las propiedades de las definiciones de tabla?

¿La huella de la memoria de almacenamiento en caché superará el uso de la CPU de reflexión?

+20

¿Cómo en el mundo obtuve un voto negativo sobre un tema que tiene 3 meses de edad y me respondieron? –

+0

Hemos automatizado nuestra capa de acceso a los datos utilizando clases base genéricas y reflexión. La mayoría de nuestras clases base genéricas se implementan mediante la reflexión. Esto ha reducido drásticamente la cantidad de líneas de código que tenemos que escribir para tareas repetitivas. Pero ha habido un golpe de rendimiento. ¿Qué solución adoptaste? –

+0

fuimos con un enfoque muy similar y ahora estamos guardando en caché los metadatos. –

Respuesta

53

La reflexión requiere una gran cantidad de metadatos del tipo que se cargarán y procesarán. Esto puede provocar una sobrecarga de memoria más grande y una ejecución más lenta. De acuerdo con this article, la modificación de la propiedad es aproximadamente 2.5x-3x más lenta y la invocación del método es 3.5x-4x más lenta.

Aquí hay una excelente MSDN article que describe cómo hacer la reflexión más rápido y dónde está la sobrecarga. Recomiendo leer si quieres saber más.

También hay un elemento de complejidad que la reflexión puede agregar al código que lo hace mucho más confuso y, por lo tanto, más difícil de trabajar. Algunas personas, como Scott Hanselman, creen que al usar la reflexión a menudo se generan más problemas de los que se resuelven. Este es especialmente el caso si sus equipos son en su mayoría desarrolladores junior.

Puede que sea mejor que busque en el DLR (Dynamic Language Runtime) si necesita mucho comportamiento dinámico. Con los nuevos cambios que vienen en .NET 4.0, es posible que desee ver si puede incorporar algo de eso en su solución. El soporte adicional para la dinámica de VB y C# hace que el uso del código dinámico sea muy elegante y la creación de sus propios objetos dinámicos bastante sencillo.

Buena suerte.

EDIT: Hice un poco más hurgando en el sitio de Scott y encontré este podcast en la reflexión. No lo escuché, pero podría valer la pena.

+0

El enlace a http://www.hanselman.com/ no va a un artículo sobre reflexión. – user1069816

+0

@ user1069816, no encontré un artículo en particular de Scott sobre el costo de la reflexión. Lo ha mencionado varias veces en su Podcast de pasada y profundizó en el tema en [Hanselminutes 27 - Reflection] (http://www.hanselminutes.com/27/reflection). – smaclell

2

Con gran potencia viene una gran responsabilidad.

Como dices, la reflexión tiene costos asociados con ella, y dependiendo de la cantidad de reflexión que hagas, puede ralentizar la aplicación significativamente.

Uno de los lugares más adecuados para usar es para IoC (Inversión de control) ya que, dependiendo del tamaño de su aplicación, probablemente tendría más beneficios que no.

+0

+1 para cita del tío de Peter de Spiderman –

1

Gracias por los excelentes enlaces y excelentes comentarios, especialmente por parte de Jr Devs, que dieron en el clavo.

Para nosotros es más fácil para los desarrolladores de nuestros jóvenes para hacer esto:

[TableName("Table")] 
public class SomeDal : BaseDal 
{ 
    [FieldName("Field")] 
    public string Field 
} 

en lugar de algunos impelementations más grandes de DAL.Esto acelera su construcción de los objetos DAL, a la vez que oculta todo el funcionamiento interno para que los desarrolladores sénior lo destruyan.

Lástima que LINQ no salió antes, creo que a veces escribimos la mitad.

+0

Aparentemente NHibernate es bastante bueno, según los chicos de ALT.NET, por lo que valdría la pena echarle un vistazo si quieres una alternativa. El último equipo en el que participé tenía una capa personalizada de ORM que usaba mucho la reflexión. Solo una persona fue capaz de entenderlo. – smaclell

+0

Nuestra solución final fue envolver esta capa lo suficientemente bien para que, si tenemos tiempo más tarde en el proyecto, sea posible eliminar la capa. Buena suerte y siento tu dolor. – smaclell

15

Hay muchas cosas que puede hacer para acelerar la reflexión. Por ejemplo, si está haciendo un montón de acceso a la propiedad, entonces HyperDescriptor podría ser útil.

Si está realizando una gran cantidad de invocación de método, puede almacenar en caché los métodos para delegados con tipeo usando Delegate.CreateDelegate; esto hace la comprobación de tipo, etc. una sola vez (durante CreateDelegate).

Si usted está haciendo un montón de obras objeto, entonces Delegate.CreateDelegate no ayudará (no se puede utilizar en un constructor) - pero (en 3.5) Expression se puede utilizar para hacer esto, de nuevo la compilación en un mecanografiada delegar.

Así que sí: el reflejo es lento, pero puede optimizarlo sin demasiado dolor.

+2

Es increíble la cantidad de personas que no conocen Delegate.CreateDelegate, de hecho, ¡es probable que tenga los mejores documentos de MSDN! – leppie

+1

Enlace a MSDN para 'CreateDelegate' http://msdn.microsoft.com/en-us/library/system.delegate.createdelegate.aspx – Dennis

0

Una cosa que a veces puede morderte cuando usas la reflexión no es actualizar las llamadas usando la reflexión al hacer la refactorización. Herramientas como resharper le solicitarán que actualice los comentarios y las cadenas cuando cambie el nombre de un método, de modo que pueda captar la mayoría de ellos de esa manera, pero cuando llame a métodos que se generaron dinámicamente o se generó dinámicamente el nombre del método, es posible que perder algo

La única solución es una buena documentación y pruebas exhaustivas de la unidad.

Cuestiones relacionadas