2009-07-02 17 views
10

Tengo un controlador de eventos que necesita determinar un tipo y ejecutar código si coincide con un tipo específico. Originalmente lo lanzamos a un objeto y si no era nulo, ejecutamos el código, para acelerarlo utilicé la reflexión y en realidad la ralentizó y no entiendo por qué.¿Por qué el fundido es más rápido que el reflejo en .NET?

aquí es un ejemplo de código

Trace.Write("Starting using Reflection"); 
if (e.Item.GetType() == typeof(GridDataItem)) 
{ 
     bool isWatch = Convert.ToBoolean(e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["IsWatch"]); 
     if (isWatch) 
     { 
      e.Item.Style["Font-Weight"] = "bold"; 
     } 
} 
Trace.Write("Ending using Reflection"); 
Trace.Write("Starting using Cast"); 
GridDataItem gridItem = e.Item as GridDataItem; 
if (gridItem !=null) 
{ 
    bool isWatch = Convert.ToBoolean(gridItem.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["IsWatch"]); 
    if (isWatch) 
    { 
     gridItem.Style["Font-Weight"] = "bold"; 
    } 
    } 
    Trace.Write("Ending using Cast"); 

Y este es el resultado de seguimiento consigo

Starting using Reflection 0.79137944962406 0.576538 
Ending using Reflection 0.791600842105263 0.000221 
Starting using Cast 0.791623353383459 0.000023 
Ending using Cast  0.791649308270677 0.000026 
Starting using Reflection 0.876253801503759 0.084604 
Ending using Reflection 0.87631790075188 0.000064 
Starting using Cast 0.87633445112782 0.000017 
Ending using Cast  0.87634950075188 0.000015 

que no es mucho, pero si tuviéramos que hacer esto mucho con el tiempo se podría añadir arriba.

+3

_Todo_ podría sumar con el tiempo. A menos que tenga evidencia de que esto 'en realidad' suma con el tiempo, no se preocupe por ello. –

+0

Se trata más de las mejores prácticas, si el casting es más rápido, entonces debería usar el casting en lugar de la reflexión –

+0

Esa lógica no se sigue del todo. Si el casting es CORRECTO, deberías usar casting en lugar de reflection. La corrección es más importante que la velocidad. –

Respuesta

15

La reflexión es lento debido a que está consultando los metadatos del montaje mientras que la fundición simplemente cambia el tipo del objeto que está haciendo referencia.

Los metadatos del ensamblado son un almacén de información útil, pero esa información se utiliza mejor en compilación tiempo en lugar de tiempo de ejecución. Ese metadato es utilizado por el compilador para la verificación de tipo estático (entre otras cosas). Está utilizando los mismos metadatos para buscar información de tipo en el momento de la ejecución (lo cual está bien si no tiene otra opción) que es significativamente más lenta que el lanzamiento.

3

reflexión tiene que ir en tiempo de ejecución y determinar qué propiedades etc el objeto tiene en tiempo de ejecución. Casting le dice a la aplicación que debe esperar que un objeto tenga propiedades X y funcione de cierta manera.

2

Fundición dice que el tiempo de ejecución "sabe" el tipo de un objeto en particular. Si bien es posible que se equivoque, el tiempo de ejecución cree que es así y no se toma el tiempo adicional necesario para verificar los metadatos del conjunto.

1

Por qué no está usando el is operator? Creo que es más legible ya que no tienes el yeso explícito, luego verifica. Simplemente verifica que la variable sea del tipo correcto.

if (e.Item is GridDataItem) 
{ 
    bool isWatch = Convert.ToBoolean(e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["IsWatch"]); 
    if (isWatch) 
    { 
     e.Item.Style["Font-Weight"] = "bold"; 
    } 
} 
+0

en realidad " es "hace un yeso bajo las sábanas". –

+0

Mi punto es que simplifica el código (haciéndolo más legible), no que haga algo fundamentalmente diferente. Lo aclararé – tvanfosson

+0

Eso es realmente más lento \t Comenzando \t 1.5268064962406 \t 1,311905 \t Terminar \t 1,52701457443609 \t 0,000208 \t partir \t 1,59114193383459 \t 0,064127 \t Terminar \t 1.59120311278195 \t 0.000061 –

0

Bien, una respuesta breve a la parte de mejores prácticas sería nunca utilizar el reflejo si se puede obtener el mismo resultado con el código normal.

Cuando la optimización de código por lo general es una buena idea para estimar que la optimización de tiempo dará lugar a la mayor ganancia de rendimiento. reimplementar los operadores de forma nativa en el idioma rara vez va a estar en la cima de la lista

1

Los yesos se puede hacer comparaciones como enteros dentro del tiempo de ejecución, pero la reflexión implica llamadas a métodos completos.

Cuestiones relacionadas