2009-10-23 15 views
12

Actualmente tengo una función:Para almacenar en caché o no a almacenar en caché - GetCustomAttributes

public static Attribute GetAttribute(MemberInfo Member, Type AttributeType) 
{ 
    Object[] Attributes = Member.GetCustomAttributes(AttributeType, true); 

    if (Attributes.Length > 0) 
     return (Attribute)Attributes[0]; 
    else 
     return null; 
} 

Me pregunto si sería conveniente almacenar en caché todos los atributos de una propiedad en un diccionario Attribute = _cache[MemberInfo][Type],

Este requeriría usar GetCustomAttributes sin ningún parámetro de tipo y luego enumerar el resultado. ¿Vale la pena?

Respuesta

13

Obtendrá mejores explosiones por tu dinero si se reemplaza el cuerpo de su método con esto:

return Attribute.GetCustomAttribute(Member, AttributeType,false); // only look in the current member and don't go up the inheritance tree. 

Si realmente necesita para almacenar en caché en un tipo-base:

public static class MyCacheFor<T> 
{ 
    static MyCacheFor() 
    { 
     // grab the data 
     Value = ExtractExpensiveData(typeof(T)); 
    } 

    public static readonly MyExpensiveToExtractData Value; 

    private static MyExpensiveToExtractData ExtractExpensiveData(Type type) 
    { 
     // ... 
    } 
} 

Beats búsquedas en el diccionario cada vez. Además de que es multi-hilo :)

Saludos, Florian

PS: Depende de con qué frecuencia se llama a esto.He tenido algunos casos en los que realizan una gran cantidad de serialización utilizando la reflexión realmente necesario el almacenamiento en caché, como de costumbre, el modus motus es la siguiente:

  1. Escribir
  2. prueba
  3. depuración
  4. prueba de nuevo
  5. CPU
  6. perfil
  7. Mem perfil
  8. Optimizar
  9. prueba una vez más
  10. Perfil CPU
  11. MEM Perfil Esto es importante ya que la optimización del código depende de la CPU sin duda trasladar la carga a la memoria
+0

Estoy haciendo serialización a través de la reflexión, por lo que indica que puede valer la pena hacerlo en algún momento. Sin embargo, como todo el mundo ha dicho, no tiene sentido optimizar hasta que sea un problema :) Saludos –

+4

En este caso, permítanme compartir un truco: si va a almacenar en caché algo donde la clave es un tipo, use un tipo genérico que una tabla hash. Actualicé mi código arriba –

6

La única forma en que puede estar seguro, es perfilarlo. Lo siento si esto suena como un cliché. Pero la razón por la cual un dicho es un cliché es a menudo porque es verdad.

Almacenar el atributo en caché hace que el código sea más complejo y más propenso a errores. Así que es posible que desee tener esto en cuenta, su tiempo de desarrollo, antes de decidir.

Así que al igual que la optimización, no lo haga a menos que sea necesario.

Según mi experiencia (estoy hablando de la aplicación de AutoCAD para Windows, con muchas operaciones de GUI y gran cantidad de crujidos), la lectura del atributo personalizado nunca es, ni siquiera una vez, el cuello de botella de rendimiento .

+0

por desgracia no tengo herramientas de perfilado disponibles para poder probar prop erly. Probablemente sea prematuro, ya que supongo que es una función de nivel razonablemente bajo en mi aplicación. Quería sacar el máximo provecho de ella. –

+0

Courtney: Puede hacer un perfil simple llamando a cada implementación en un ciclo que se repite muchas veces, y mida cuánto tarda cada vista en ejecutarse. Realmente no necesitas un generador de perfiles en este caso. –

3

¿De verdad está teniendo un problema de rendimiento? Si no, no lo hagas hasta que lo necesites.

Puede ser útil dependiendo de la frecuencia con la que llame al método con los mismos parámetros. Si solo lo llama una vez por MemberInfo, Type combinación, entonces no servirá de nada. Incluso si lo almacena en caché, está negociando velocidad para el consumo de memoria. Eso podría estar bien para su aplicación.

5

Su pregunta es un caso de optimización prematura.

No conoce el funcionamiento interno de las clases de reflexión y, por lo tanto, está haciendo suposiciones sobre las implicaciones de rendimiento de llamar al GetCustomAttributes varias veces. El método en sí mismo bien podría almacenar en caché su salida, lo que significa que su código realmente agregaría gastos generales sin mejorar el rendimiento.

¡Ahorre sus ciclos cerebrales para pensar en cosas que ya sabe que son problemas!

+0

De hecho iba a decir en la pregunta pero terminé editándolo, no sé si lo hace internamente. –

0

solo tuve un escenario en el que GetCustomAttributes resultó ser el cuello de botella . En mi caso, fue llamado cientos de miles de veces en un conjunto de datos con muchas filas y esto hizo que el problema fuera fácil de aislar. Almacenar en caché los atributos resolvió el problema.

Las pruebas preliminares condujeron a un rendimiento apenas perceptible en alrededor de 5000 llamadas en una máquina moderna. (Y se volvió drásticamente más notorio a medida que aumentaba el tamaño del conjunto de datos.)

En general, estoy de acuerdo con las otras respuestas sobre la optimización prematura, sin embargo, en una escala de instrucción de CPU a llamada DB, sugiero que GetCustomAttributes se inclinaría más hacia este último

Cuestiones relacionadas