Riflessione: usare la riflessione è ancora "cattivo" o "lento"? Cosa è cambiato con la riflessione dal 2002?


21

Ho notato quando ho a che fare con espressioni o alberi delle espressioni sto usando molto la riflessione per impostare e ottenere valori nelle proprietà e cosa hai. Mi è venuto in mente che l'uso della riflessione sembra essere sempre più comune. Cose come DataAnotations per la convalida, Attributi ORM pesanti, ecc. Mi chiedo: cosa è cambiato dai giorni, anni e anni fa, quando mi veniva detto di evitare la riflessione, se possibile?

E allora, se qualcosa è cambiato? È solo la velocità delle macchine? Sono state apportate modifiche al framework per accelerare la riflessione?

O non è cambiato davvero nulla? È ancora "cattivo" o "lento" usare la riflessione?


2
La riflessione sarà sempre più lenta delle chiamate dirette, poiché è necessario eseguire diversi passaggi per trovare e verificare l'esistenza di ciò che si sta chiamando.
Michael K,

È sempre stato male ... Certo a volte non hai scelta, spetta al programmatore sapere quando sono quei tempi ed evitarlo altrimenti.
Ramhound,

L'esecuzione di un Reflection con gettype per estrarre un elemento in un enum è ancora oltre 30 volte più veloce rispetto al lancio di un'eccezione con Enum.Parse (). Quindi a volte vince la riflessione.
Brain2000,

Risposte:


16

La riflessione non è né cattiva, né lenta. È semplicemente uno strumento. Come tutti gli strumenti, è molto prezioso per alcuni scenari, non così prezioso per altri.

Se le prestazioni sono davvero un problema, puoi sempre utilizzare una libreria come FasterFlect .

Ulteriori letture
Se la riflessione è inefficiente, quando è più appropriato?


Oppure dynamic- apparentemente un ordine di grandezza più veloce della riflessione.
Oded,

1
Le prestazioni non sono affatto un problema. Ricordo vividamente la gente che evitava la riflessione nel 2002 come se fosse la peste. Mi chiedo cosa sia cambiato da allora.
carne

3
@blesh: niente. Le persone lo conoscono più adesso e ne hanno meno paura.
Robert Harvey,

5
Potrei essere tutti "scendere dal mio prato" qui e dire che Lisp aveva così tanto tempo prima che esistesse OOP ...
Michael K,

Giusto. Mi stavo solo chiedendo se sono stati gli aumenti di velocità nelle macchine negli ultimi dieci anni a fare la differenza o se ci sono state effettivamente delle modifiche apportate a System.Reflection che hanno migliorato le prestazioni.
carne

17

Il motivo per cui le persone sono caute nell'usare inutilmente la riflessione non è la prestazione: sì, c'è qualche sovraccarico nell'usare la riflessione, ma spesso, risolvere il problema senza di esso richiede un approccio diverso con complessità comparabile, e anche se non lo è, l'overhead è raramente significativo (specialmente per lo sviluppo a livello di applicazione).

Usando la riflessione, alcune importanti ipotesi che si possono fare sul codice sorgente vengono infrante e strumenti come "Trova tutti i riferimenti" cessano di funzionare in modo affidabile. Reflection rimuove sostanzialmente anche la maggior parte della sicurezza del tipo in cui il compilatore applica, per esempio, C #, e la maggior parte degli errori di programmazione che un sistema di tipo normalmente rileva e traduce in errori del compilatore, ora diventano errori di runtime nella migliore delle ipotesi o bug molto oscuri nella peggiore.

Allora perché le persone usano la riflessione? In poche parole, perché nonostante i problemi sopra descritti, è uno strumento molto prezioso. Con la riflessione, alcuni dei vantaggi della programmazione dinamica possono essere ottenuti in un linguaggio statico e tipicamente rigoroso come C #, e i linguaggi di programmazione dinamica hanno mostrato recentemente i loro meriti, specialmente nel regno della programmazione web - PHP, Javascript e in particolare Python , tutti usano la digitazione dinamica e hanno dimostrato di essere adatti alla programmazione web. Ma poiché il linguaggio è ancora C #, puoi scegliere di mantenere la maggior parte della tua applicazione in un linguaggio OOP tipicamente tipizzato e scrivere la piccola parte in cui il comportamento dinamico fa davvero la differenza con la riflessione.

Un esempio tipico è quando è necessario esporre metodi come chiamate di servizi Web (utilizzando un protocollo non ancora incorporato in .NET). L'approccio OOP tipizzato rigorosamente funziona, ma è eccessivamente restrittivo e goffo. Ma se usi la riflessione per mappare le chiamate ai metodi e le coppie chiave / valore agli argomenti, puoi scrivere l'impianto idraulico per tale servizio Web una volta e poi utilizzarlo su qualsiasi classe ti piaccia.


13

La riflessione è ancora significativamente più lenta delle chiamate dirette. Sono cambiate due cose:

  • L'autonomia ha ottimizzato i meccanismi di riflessione in modo che la differenza sia diminuita
  • Le CPU sono diventate più veloci in modo che le piccole inefficienze siano più facili da tollerare

Insieme, questi due fattori hanno portato il costo della riflessione al punto in cui è possibile usarlo di routine (se del caso da un POV di manutenibilità) e attendere che il profiler ti dica se si tratta effettivamente di un collo di bottiglia (ed essere ragionevolmente sicuri che la maggior parte di il tempo non sarà).


4
ahimè, le CPU sono diventate più lente, in genere sui dispositivi mobili, e sul server in cui le persone stanno cercando di spremere quanta più efficienza possibile dai loro server a causa dei costi di gestione.
gbjbaanb,

@gbjbaanb: ti darò i dispositivi mobili, ma sul server, acquistare più hardware anziché ottimizzare il codice è la scelta accettata e razionale nella stragrande maggioranza dei casi, perché i costi di acquisto e gestione dei server sono molto più bassi di i costi di ottimizzazione del codice.
Michael Borgwardt,

2
In alcune situazioni i costi del server superano notevolmente i costi di sviluppo. In grande scala. Anche se i server sono buff, le prestazioni possono essere persino più critiche che su un computer client. È uno scenario caso per caso.
Lord Tydus,

1
@Lord Tydus: certo, ma il caso che descrivi è la rara eccezione.
Michael Borgwardt,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.