2012-04-16 6 views
12

Si consideri il seguente codice ...Perché sta usando un Func <> in modo molto più veloce rispetto all'uso del nuovo vincolo() su un creatore generica sequenza

Nel mio test per una versione (non eseguire il debug!) X86 costruire su Windows 7 x64 PC (Intel i7 3GHz) ho ottenuto i seguenti risultati:

CreateSequence() with new() took 00:00:00.9158071 
CreateSequence() with creator() took 00:00:00.1383482 

CreateSequence() with new() took 00:00:00.9198317 
CreateSequence() with creator() took 00:00:00.1372920 

CreateSequence() with new() took 00:00:00.9340462 
CreateSequence() with creator() took 00:00:00.1447375 

CreateSequence() with new() took 00:00:00.9344077 
CreateSequence() with creator() took 00:00:00.1365162 

sembra che l'utilizzo di un Func <> per definire un delegato per creare nuovi oggetti è più di 6 volte più veloce di chiamare "new T() "direttamente.

Trovo che questo sia un po 'inaspettato ... Immagino che sia a causa di qualche inlining fatto dal Jitter, ma avrei pensato che sarebbe stato in grado di ottimizzare la "nuova T()" altrettanto bene.

Qualcuno ha una spiegazione per questo?

Forse sto facendo un errore. (Ho considerato l'effetto che il garbage collector potrebbe avere, ma riorganizzare il codice e aggiungere GC.Collect() e così via non cambia significativamente i risultati).

Comunque, ecco il codice:

+10

Vedere https://msmvps.com/blogs/jon_skeet/archive/2011/08/22/optimization-and-generics-part-1-the-new-constraint.aspx –

+0

correlati: http: // stackoverflow. it/questions/367577/why-does-the-c-sharp-compiler-emit-activator-createinstance-when-calling-new-in – nawfal

risposta

13

Il vincolo new() assicura solo che il tipo in passato ha un costruttore senza parametri. Se si chiama in realtà new T() (o qualsiasi altro nome il tipo di argomento è), in realtà fa questo:

Activator.CreateInstance<T>(); 

Il che, al suo interno, utilizza la riflessione.

+1

Grazie (e anche a Jon, per l'interessante articolo). Sembra che il nuovo vincolo() dovrebbe essere evitato quando hai bisogno di un codice molto veloce e puoi invece usare l'approccio "Func <> creatore"! –

+1

@MatthewWatson: questo è quello che suggerirei –

+1

Per quanto riguarda il motivo, vedere http://stackoverflow.com/questions/367577/why-does-the-c-sharp-compiler-emit-activator-createinstance-when- chiamando-new-in – nawfal

Problemi correlati