2009-06-22 8 views
18

Necesito establecer dinámicamente valores en un grupo o propiedades en un objeto, llámalo un objeto de transmisión. Habrá un buen número de estos objetos de transmisión que se crearán y tendrán sus propiedades establecidas en un corto espacio de tiempo. Quiero evitar el uso de la reflexión, ¿hay alternativ? Si es así, ¿hay implementaciones de muestra que podría ver?Mejorando la reflexión del rendimiento, qué alternativas debería considerar

Gracias

+1

¿Alguna razón por la que desea evitar la reflexión? –

Respuesta

21

Usa Delegate.CreateDelegate para convertir MethodInfo en un delegado fuertemente tipado. Esto puede mejorar el rendimiento masivamente. Tengo un blog post about this con código de muestra. Tenga en cuenta que esto solo ayudará si necesita establecer las mismas propiedades varias veces, básicamente significa que una gran parte de la verificación de tipo se realiza una vez cuando crea el delegado, en lugar de en cada invocación.

Marc Gravell tiene un proyecto HyperPropertyDescriptor que logra un rendimiento aún mejor, pero introduce una dependencia adicional. Este proyecto se convirtió en el punto de partida para el más moderno Fast Member (github). En general, usaría Fast Member sobre HyperProperty.

+0

Lo tengo gracias http://msmvps.com/blogs/jon_skeet/archive/2008/08/09/making-reflection-fly-and-exploring-delegates.aspx – AndyMM

+0

Eso es mucho mejor que tratar de hacer un método dinámico – JoshBerke

+0

Tengo algunos ejemplos interesantes de esto en .NET 4.0 con árboles DLR - con suerte para el artículo ;-p –

0

¿Usted ha establecido con certeza que el uso de la reflexión es demasiado lento? Aunque el reflejo en .NET es no tan rápido como código estático, sigue siendo extremadamente rápido. Debería escribir el código de la manera más fácil posible, incluso si eso utiliza la reflexión, y solo volver a optimizarlo si observa problemas de rendimiento y los aísla al uso de la reflexión. La mayoría de las veces, no tendrás ningún problema. Reflection se utiliza en todo tipo de código sensible al rendimiento, como ASP.NET MVC.

+0

Supongo que lo que estoy buscando es la implementación más rápida posible. También estoy buscando alternativas simplemente para la debida diligencia. No quiero quedar atrapado en una sola técnica, simplemente porque es con la que estoy familiarizado, sin explorar alternativas. – AndyMM

0

reflexión tiene una mala reputación desde Java donde está (o al menos usa ser) muy lento. Este no es el caso en .net así que no entiendo su objeción al usarlo. También estoy de acuerdo con Rex, no se puede decir que algo tiene un rendimiento pobre sin medir realmente.

+0

¡No dije que tuviera un rendimiento deficiente, lo insinué! bromas a un lado por favor ver comentario a rex. – AndyMM

+0

Depende de lo que quieras decir con "muy lento". Todavía puede ser un cuello de botella si lo usa ingenuamente ... pero con un poco de trabajo (por ejemplo, Delegate.CreateDelegate y similares) se puede hacer bastante nippy. –

2

La reflexión puede ser asombrosamente rápida si lo haces bien (no tan rápido como el código estático, por supuesto).

Encontrar una propiedad-setter es lento. Invocar a un delegado es rápido.

que necesita para obtener y caché Delegate objetos para cada propiedad sets para cada tipo de DTO. Esa es la parte lenta, pero es un golpe de una sola vez. A continuación, puede Invoke cada uno de los delegados en caché para los emisores de propiedades de un tipo de DTO determinado, pasando el objeto DTO y el nuevo valor de propiedad, pero esta parte será muy rápida.

+1

Gracias, Justicia, voy a intentar tu idea. – AndyMM

5

En .NET 4.0 (beta), puede hacer esto con los árboles de expresiones actualizados, usando Expression.Block y Expression.Assign - luego, compile eso a un delegado tipeado; trabajo hecho.

En .NET 2.0 y por encima (como se mencionó Jon) HyperDescriptor es una opción razonable - que funciona como una implementación personalizada PropertyDescriptor, por lo que acaba de hacer un código como:

// store this collection for optimum performance 
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(
    typeof(SomeType)); 
props["Name"].SetValue(obj, newName); 
props["DateOfBirth"].SetValue(obj, newDoB); 

Esto todavía tiene un poco de boxeo, pero que no es en realidad una embotellamiento.

Cuestiones relacionadas