2009-10-23 12 views
12

Al momento ho una funzione:Per memorizzare nella cache o di non memorizzare nella cache - 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; 
} 

mi chiedo se sarebbe utile la memorizzazione nella cache tutti gli attributi di una proprietà in un dizionario Attribute = _cache[MemberInfo][Type],

Questo richiederebbe l'utilizzo di GetCustomAttributes senza alcun parametro di tipo quindi elencando il risultato. Ne vale la pena?

risposta

13

Otterrete frangia migliori per i vostri soldi se si sostituisce il corpo del metodo con questo:

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

Se avete veramente bisogno di memorizzare nella cache su 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 ricerche di dizionari ogni volta. In più è threadsafe :)

Cheers, Florian

PS: dipende da come spesso si chiama questo.Ho avuto alcuni casi in cui facendo un sacco di serializzazione utilizzando la riflessione davvero chiamato per il caching, come al solito, l'operandi Motus è questo:

  1. Scrivi
  2. prova
  3. Debug
  4. prova di nuovo
  5. CPU profilo
  6. Mem profilo
  7. Ottimizzare
  8. prova una volta di più
  9. CPU Profilo
  10. MEM Profilo Questo è importante in quanto l'ottimizzazione del codice di cpu legato certamente spostare l'onere alla memoria
+0

Sto facendo la serializzazione tramite la riflessione in modo che indichi che potrebbe valere la pena farlo a un certo punto. Tuttavia, come hanno detto tutti qui, non c'è motivo di ottimizzarlo fino a quando non è un problema :) Saluti –

+4

In questo caso, fammi condividere un trucco: se stai andando a mettere in cache qualcosa in cui la tua chiave è un tipo, usa un tipo generico piuttosto di un hashtable. Ho aggiornato il mio codice sopra –

6

L'unico modo che si può sapere con certezza è di profilarlo. Mi dispiace se sembra un cliché. Ma il motivo per cui un detto è un cliché è spesso perché è vero.

La memorizzazione nella cache dell'attributo sta rendendo il codice più complesso e più soggetto a errori. Quindi potresti prendere in considerazione questo, il tuo tempo di sviluppo, prima di decidere.

Così come l'ottimizzazione, non farlo a meno che non sia necessario.

Dalla mia esperienza (sto parlando di AutoCAD come Windows Application, con un sacco di operazioni GUI click-modificare e il numero pesante scricchiolio), la lettura di attributo personalizzato non è mai - anche once-- il collo di bottiglia delle prestazioni .

+0

Ahimè non ho strumenti di profiling a disposizione per essere in grado di testare prop erly. Probabilmente è prematuro, immaginando che si tratta di una funzione di livello relativamente basso nella mia app che volevo ottenere il massimo da esso. –

+0

Courtney: è possibile eseguire una semplice profilazione chiamando ogni implementazione in un ciclo che si ripete molte volte e misurare la durata di esecuzione di ogni look. In questo caso non hai davvero bisogno di un profiler. –

3

Stai riscontrando un problema di prestazioni? Altrimenti, non farlo finché non ne hai bisogno.

Potrebbe essere utile a seconda della frequenza con cui si chiama il metodo con gli stessi parametri. Se la chiami solo una volta per combinazione MemberInfo, Type, allora non servirà a nulla. Anche se lo si memorizza nella cache, si sta sfruttando la velocità per il consumo di memoria. Potrebbe andare bene per la tua applicazione.

5

La tua domanda è un caso di ottimizzazione prematura.

Non si conoscono i meccanismi interni delle classi di riflessione e pertanto si stanno formando ipotesi sulle implicazioni delle prestazioni della chiamata allo GetCustomAttributes più volte. Il metodo stesso potrebbe già memorizzare nella cache l'output, il che significa che il tuo codice aggiungerà effettivamente un sovraccarico senza alcun miglioramento delle prestazioni.

Salva i tuoi cicli cerebrali per pensare a cose che già conosci sono problemi!

+0

In realtà stavo per dire nella domanda ma alla fine ho deciso di non sapere se lo fa internamente. –

0

Ho appena avuto uno scenario in cui GetCustomAttributes si è rivelato essere il collo di bottiglia delle prestazioni . Nel mio caso è stato chiamato centinaia di migliaia di volte in un set di dati con molte righe e questo ha reso il problema facile da isolare. Il caching degli attributi ha risolto il problema.

I test preliminari hanno provocato un calo delle prestazioni appena percettibile a circa 5000 chiamate su una macchina moderna. (E divenne drasticamente più evidente quando le dimensioni del set di dati aumentarono.)

Generalmente sono d'accordo con le altre risposte sull'ottimizzazione prematura, tuttavia, su una scala di istruzioni della CPU per la chiamata DB, suggerirei che GetCustomAttributes si piegherebbe di più verso il secondo.

Problemi correlati