Reflexion: Ist die Verwendung von Reflexion immer noch „schlecht“ oder „langsam“? Was hat sich seit 2002 mit Reflektion geändert?

21

Ich habe festgestellt, dass ich beim Umgang mit Ausdrücken oder Ausdrucksbäumen viel Reflexion verwende, um Werte in Eigenschaften festzulegen und abzurufen, und was Sie haben. Mir ist aufgefallen, dass die Verwendung von Reflexion immer häufiger zu werden scheint. Dinge wie DataAnotations zur Validierung, Attribute Heavy ORMs usw. Haben Sie sich gefragt: Was hat sich seit den Tagen und Jahren geändert, als mir gesagt wurde, dass ich Reflexionen möglichst vermeiden soll?

Was ist, wenn sich etwas geändert hat? Ist es nur die Geschwindigkeit der Maschinen? Wurden Änderungen am Framework vorgenommen, um die Reflexion zu beschleunigen?

Oder hat sich nichts wirklich geändert? Ist es immer noch "schlecht" oder "langsam", Reflexion zu verwenden?

Fleisch
quelle
2
Die Reflexion ist immer langsamer als bei direkten Anrufen, da Sie mehrere Schritte ausführen müssen, um zu ermitteln und zu überprüfen, ob das, was Sie anrufen, vorhanden ist.
Michael K
Es war immer schlecht .... Natürlich hat man manchmal keine andere Wahl, es liegt am Programmierer, zu wissen, wann diese Zeiten sind, und es ansonsten zu vermeiden.
Ramhound
Das Ausführen einer Reflektion mit gettype zum Abrufen eines Elements in einer Aufzählung ist immer noch über 30-mal schneller als das Auslösen einer Ausnahme mit Enum.Parse (). So gewinnt das Nachdenken manchmal.
Brain2000

Antworten:

16

Reflexion ist weder schlecht noch langsam. Es ist einfach ein Werkzeug. Wie alle Tools ist es für bestimmte Szenarien sehr wertvoll, für andere weniger.

Wenn Leistung wirklich ein Problem ist, können Sie immer eine Bibliothek wie FasterFlect verwenden .

Weitere Informationen
Wenn die Reflexion ineffizient ist, wann ist sie am besten geeignet?

Robert Harvey
quelle
Oder dynamic- anscheinend eine Größenordnung schneller als Reflexion.
Oded
1
Leistung ist überhaupt kein Problem. Ich erinnere mich lebhaft an Menschen, die im Jahr 2002 das Nachdenken vermieden haben, als wäre es die Pest gewesen. Ich frage mich, was sich seitdem geändert hat.
Fleisch
3
@blesh: Nichts. Die Leute kennen es jetzt besser und haben weniger Angst davor.
Robert Harvey
5
Ich könnte alle "runter von meinem Rasen" hier sein und sagen, dass Lisp dies lange bevor OOP existierte hatte ...
Michael K
Meinetwegen. Ich habe mich nur gefragt, ob es die Geschwindigkeitssteigerungen bei Maschinen in den letzten zehn Jahren waren, die den Unterschied ausmachten, oder ob tatsächlich Änderungen an System.Reflex vorgenommen wurden, die die Leistung gesteigert haben.
Fleisch
17

Der Grund, warum die Leute nicht unnötig auf Reflexion achten, ist nicht die Leistung: Ja, die Verwendung von Reflexion ist mit einem gewissen Aufwand verbunden, aber häufig erfordert die Lösung des Problems ohne Reflexion einen anderen Ansatz mit vergleichbarer Komplexität, und selbst wenn dies nicht der Fall ist, ist dies der Aufwand selten von Bedeutung (insbesondere für die Entwicklung auf Anwendungsebene).

Bei der Verwendung von Reflection sind einige wichtige Annahmen, die man normalerweise zum Quellcode machen kann, fehlerhaft, und Tools wie "Alle Verweise suchen" funktionieren nicht mehr zuverlässig. Reflection beseitigt im Grunde genommen auch den größten Teil der Typensicherheit, die der Compiler beispielsweise in C # erzwingt, und die meisten Programmierfehler, die ein Typensystem normalerweise abfängt und in Compilerfehler umsetzt, werden im besten Fall zu Laufzeitfehlern oder im schlimmsten Fall zu sehr undurchsichtigen Fehlern.

Warum verwenden die Leute dann Reflexion? Einfach ausgedrückt, weil es trotz der oben beschriebenen Probleme ein sehr wertvolles Werkzeug ist. Mit Reflektion können einige der Vorteile der dynamischen Programmierung in einer statischen, streng typisierten Sprache wie C # erzielt werden, und dynamische Programmiersprachen haben in letzter Zeit ihre Vorzüge gezeigt, insbesondere im Bereich der Webprogrammierung - PHP, Javascript und ganz prominent Python verwenden alle dynamische Typisierung und haben sich als gut für die Webprogrammierung erwiesen. Da die Sprache jedoch immer noch C # ist, können Sie den größten Teil Ihrer Anwendung in einer streng typisierten OOP-Sprache speichern und den kleinen Teil schreiben, in dem dynamisches Verhalten bei der Reflexion wirklich einen Unterschied macht.

Ein typisches Beispiel ist, wenn Sie Methoden als Webdienstaufrufe verfügbar machen müssen (unter Verwendung eines Protokolls, das noch nicht in .NET integriert ist). Der streng typisierte OOP-Ansatz funktioniert zwar, ist jedoch zu restriktiv und umständlich. Wenn Sie jedoch Reflection verwenden, um Aufrufe von Methoden und Schlüssel / Wert-Paare Argumenten zuzuordnen, können Sie das Installationsprogramm für einen solchen Webdienst einmal schreiben und es dann für eine beliebige Klasse verwenden.

tdammers
quelle
13

Die Reflexion ist immer noch deutlich langsamer als bei direkten Anrufen. Zwei Dinge haben sich geändert:

  • Laufzeiten haben optimierte Reflexionsmechanismen, so dass die Differenz kleiner geworden ist
  • CPUs sind schneller geworden, sodass kleine Ineffizienzen leichter zu tolerieren sind

Zusammen haben diese beiden Faktoren die Reflektionskosten auf einen Punkt gesenkt, an dem Sie sie routinemäßig verwenden können (gegebenenfalls anhand eines Wartbarkeits-POV) und warten, bis der Profiler Ihnen mitteilt, ob es sich tatsächlich um einen Engpass handelt (und Sie sind sich einigermaßen sicher, dass die meisten Probleme auftreten) die Zeit wird es nicht sein).

Michael Borgwardt
quelle
4
Leider sind die CPUs langsamer geworden - in der Regel auf Mobilgeräten und auf Servern, auf denen aufgrund der Kosten für deren Betrieb versucht wird, die Server so effizient wie möglich zu gestalten.
gbjbaanb
@gbjbaanb: Ich gebe Ihnen mobile Geräte, aber auf dem Server ist es in den allermeisten Fällen die akzeptierte und rationale Wahl, mehr Hardware zu kaufen als den Code zu optimieren, da die Kosten für den Kauf und Betrieb von Servern so viel niedriger sind als die Kosten für die Optimierung des Codes.
Michael Borgwardt
2
In einigen Situationen überwiegen die Serverkosten erheblich die Entwicklungskosten. Im großen Scale-Out-Stil. Auch wenn die Leistung der Server zu hoch ist, kann die Leistung sogar noch kritischer sein als auf einem Client-Computer. Es ist ein Szenario von Fall zu Fall.
Lord Tydus
1
@ Lord Tydus: Sicher, aber der von Ihnen beschriebene Fall ist die seltene Ausnahme.
Michael Borgwardt