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.