2008-10-22 12 views
64

Mögliche Duplizieren:
How costly is .NET reflection?Was sind die "Kosten" der .NET-Reflektion?

Ich bin derzeit in einer Programmiersprache Mentalität, dass Reflexion ist mein bester Freund. Ich benutze es sehr für dynamisches Laden von Inhalten, die "losen Implementierung" statt strenge Schnittstellen, sowie eine Menge von benutzerdefinierten Attributen ermöglicht.

Was sind die "echten" Kosten für die Verwendung von Reflektion?

Lohnt es sich, häufig gespiegelte Typen im Cache zu speichern, z. B. unseren eigenen LINQ-DAL-Objektcode für alle Eigenschaften für Tabellendefinitionen?

Wäre die Speicherauslastung des Caching-Speichers größer als die Reflektions-CPU-Auslastung?

+20

wie in der welt habe ich eine abstimmung über ein thema erhalten, das 3 monate alt ist und beantwortet? –

+0

Wir haben unsere Datenzugriffsebene mit generischen Basisklassen und Reflektionen automatisiert. Die meisten unserer generischen Basisklassen werden durch Reflektion implementiert. Dies hat die Anzahl der Codezeilen, die wir für repetitive Aufgaben schreiben müssen, drastisch reduziert. Aber es gab einen Leistungseinbruch. Welche Lösung hast du übernommen? –

+0

wir gingen mit einem sehr ähnlichen Ansatz und sind jetzt Caching der Metadaten. –

Antwort

53

Reflection benötigt eine große Menge der Typ-Metadaten, die geladen und dann verarbeitet werden. Dies kann zu einem größeren Speicheraufwand und einer langsameren Ausführung führen. Gemäß this article ist die Eigenschaftsmodifikation ungefähr 2,5x-3x langsamer und der Methodenaufruf ist 3,5x-4x langsamer.

Hier ist eine hervorragende MSDN article umreißt, wie Reflektion schneller und wo der Overhead ist. Ich empfehle sehr zu lesen, wenn Sie mehr erfahren möchten.

Es gibt auch ein Element der Komplexität, das Reflektion dem Code hinzufügen kann, wodurch es wesentlich verwirrender und damit schwieriger zu bearbeiten ist. Einige Leute, wie Scott Hanselman glauben, dass durch die Verwendung von Reflektion Sie oft mehr Probleme machen, als Sie lösen. Dies ist insbesondere der Fall, wenn Ihre Teams meist Junior Devs sind.

Sie können besser in die DLR (Dynamic Language Runtime) schauen, wenn Sie viel dynamisches Verhalten benötigen. Mit den neuen Änderungen in .NET 4.0 möchten Sie vielleicht sehen, ob Sie etwas davon in Ihre Lösung integrieren können. Die zusätzliche Unterstützung für Dynamic von VB und C# macht die Verwendung von dynamischem Code sehr elegant und das Erstellen eigener dynamischer Objekte relativ einfach.

Viel Glück.

EDIT: Ich habe mehr stochern um Scott Website und fand diese podcast auf Reflexion. Ich habe es nicht gehört, aber es könnte sich lohnen.

+0

Der Link zu http://www.hanselman.com/ geht nicht auf einen Artikel über Reflexion. – user1069816

+0

@ user1069816, Ich fand keinen bestimmten Artikel von Scott über die Kosten der Reflexion. Er hat es im Vorbeigehen ein paar Mal auf seinem Podcast erwähnt und ging vertieft in das Thema [Hanselminutes 27 - Reflection] (http://www.hanselminutes.com/27/reflection). – smaclell

2

Mit großer Kraft kommt große Verantwortung.

Wie Sie sagen, hat die Reflektion mit Kosten zu tun, und je nachdem wie viel Reflektion Sie tun, kann die Anwendung erheblich verlangsamt werden.

Einer der sehr geeigneten Orte, um es zu verwenden, ist für IoC (Inversion of Control), da, je nach der Größe Ihrer Anwendung, würde wahrscheinlich mehr Vorteile als nicht haben.

+0

+1 für Peters Onkel Zitat aus Spiderman –

1

Danke für die tollen Links und tollen Kommentare, besonders seitens der Jr Devs, die es richtig auf das Geld abgesehen haben.

Für uns ist es einfacher für unsere Junior-Entwickler, dies zu tun:

[TableName("Table")] 
public class SomeDal : BaseDal 
{ 
    [FieldName("Field")] 
    public string Field 
} 

eher als einige größere impelementations von DAL.Dies beschleunigt das Erstellen der DAL-Objekte, während alle internen Vorgänge für die leitenden Entwickler verborgen bleiben.

Schade LINQ kam früher nicht heraus, ich fühle manchmal die Hälfte davon geschrieben.

+0

Anscheinend ist NHibernate ziemlich gut, nach den ALT.NET-Typen, so dass es einen Blick wert sein könnte, wenn Sie eine Alternative wollen. Das letzte Team, an dem ich beteiligt war, hatte eine benutzerdefinierte ORM-Ebene, die stark mit Reflektion arbeitete. Nur eine Person konnte es jemals verstehen. – smaclell

+0

Unsere letzte Lösung bestand darin, diese Schicht so weit einzuhüllen, dass es möglich ist, die Schicht zu entfernen, wenn wir später im Projekt Zeit haben. Viel Glück und ich fühle deinen Schmerz. – smaclell

15

Es gibt viele Dinge, die Sie tun können, um die Reflexion zu beschleunigen. Zum Beispiel, wenn Sie viel Eigentum-Zugang machen, dann HyperDescriptor könnte nützlich sein.

Wenn Sie viele Methoden aufrufen, können Sie Methoden für typisierte Delegaten zwischenspeichern, indem Sie Delegate.CreateDelegate verwenden - dies führt die Typüberprüfung usw. nur einmal durch (während CreateDelegate).

Wenn Sie eine Menge von Objektkonstruktion machen, dann Delegate.CreateDelegate wird nicht helfen (Sie können es nicht auf einen Konstruktor verwenden) - aber (in 3.5) Expression kann dazu verwendet werden, erneut kompilieren zu einem getippt delegieren.

Also ja: Reflexion ist langsam, aber Sie können es ohne zu viel Schmerz optimieren.

+2

Es ist erstaunlich, wie viele Leute nicht über Delegate.CreateDelegate wissen, tatsächlich hat es wahrscheinlich die besten MSDN-Dokumente aller Zeiten! – leppie

+1

Link zu MSDN für 'CreateDelegate' http://msdn.microsoft.com/en-us/library/system.delegate.createdelegate.aspx – Dennis

0

Eine Sache, die Sie bei der Verwendung von Reflektionen manchmal beißen kann, ist das Aktualisieren von Anrufen bei der Reflektion beim Refactoring nicht. Tools wie Resharper werden Sie auffordern, Kommentare und Strings zu aktualisieren, wenn Sie einen Methodennamen ändern, so dass Sie die meisten davon auf diese Weise abfangen können. Wenn Sie jedoch Methoden aufrufen, die dynamisch generiert wurden oder der Methodenname dynamisch generiert wurde vermisse irgendwas.

Die einzige Lösung ist eine gute Dokumentation und gründliche Komponententests.