2010-02-12 13 views
8

Sto lavorando alla creazione del mio framework DI che crei le fabbriche delegate come esercizio di apprendimento. Il mio modo di creare delegati dattiloscritti consiste nell'utilizzare espressioni per creare una funzione che richiami un metodo statico con riferimento al mio contenitore e ai parametri del costruttore.Cosa si comporta peggio: riflessione o boxe?

Questo ha sollevato una domanda interessante per quanto riguarda i tipi di valore. Che è la più performante:

a) Utilizzo di riflessione per selezionare un metodo generico statico con il numero corretto di parametri quindi utilizzare MakeGenericMethod per rimuovere i farmaci generici

b) Andare per oggetto il vecchio modo params [] e prendere il colpo sulla boxe?

+6

Qualsiasi motivo per cui questo "esercizio di apprendimento" non prevede il profiling di varie configurazioni per trovare la soluzione ottimale? ;-) Continuerò comunque a dare +1. –

+1

Buon punto, penso di sì. –

+1

c) utilizzando un sovraccarico con parametri generici? – herzmeister

risposta

16

IME, il tempo di boxe non è nulla rispetto alla riflessione.

3

Direi che la riflessione sarebbe molto più lenta, probabilmente gli ordini di magintude così.

E 'abbastanza facile da banco, però, dare un andare e pubblica i tuoi risultati :)

3

In questo caso, la boxe saranno ordini di grandezza più veloce di riflessione.

Ovviamente, è sempre possibile memorizzare nella cache i risultati della riflessione.

+1

+1 per l'ultima riga, che dovrebbe essere enfatizzata di più. – supercat

1

Se si deve elaborare un milione di articoli, il confezionamento di ciascun articolo risulterà meno efficiente rispetto all'elaborazione senza boxe, ma sarà molto più rapido rispetto all'utilizzo di Reflection per elaborare il tipo di ciascun articolo.

D'altra parte, in molti scenari sarà possibile elaborare un milione di oggetti di un certo tipo generico T utilizzando riflessione una volta, il tipo T, per costruire un oggetto in grado di elaborare qualcosa di tipo T, senza la boxe, e quindi memorizza il risultato in cache per la durata del programma. Questo è il modo in cui cose come EqualityComparer<T>.Default funzionano. Un simile approccio può facilmente essere più di un ordine di grandezza più veloce di inscatolare ogni oggetto.

+0

Ricorda, tuttavia, che avresti ancora bisogno di accedere alla cache di riflessione, molto probabilmente attraverso un dizionario. Non sarei sorpreso se un po 'di boxe fosse ancora più veloce di quelle ricerche, in particolare se sono coinvolte chiavi di stringa (che potrebbero essere o non essere il caso). – Timo

2

In generale, direi anche se la boxe è stata più lenta (in una misura non evidente), è la strada giusta da percorrere. Reflection è uno strumento per facilitare una sorta di meta-programmazione - quando devi lavorare sul codice stesso, e non per facilitare la logica di business delle tue applicazioni, e quindi non dovresti usarlo senza una buona ragione. Un programmatore dovrebbe pensare prima dal dominio fisico. Detto questo, nel tuo caso probabilmente non ha importanza dal momento che stai già andando in meta. Penso che sia. L'utilizzo di object ti dà ancora sicurezza in fase di compilazione in una certa misura e manutenzione migliore.

Come altri hanno già detto, il riflesso è il più lento qui (a meno che non si memorizzi nella cache). Un'altra cosa che viene a favore della boxe è che probabilmente sei comunque il pugilato quando si tratta di riflessione. La reflection API si occupa sempre di object, quindi se stai recuperando qualche valore di istanza devi unbox. Allo stesso modo, calling GetType on a value type instance first boxes it to object che potrebbe essere necessario se non si dispone dell'argomento di tipo, ma solo dell'istanza.

Ma un'alternativa migliore è fare affidamento sui generici.Alcuni bei modelli sono dettagliati here.

Problemi correlati