2009-06-22 6 views
18

Ich muss Werte auf einem Haufen oder Eigenschaften auf einem Objekt dynamisch festlegen, nennen Sie es ein Übertragungsobjekt. Es wird eine beträchtliche Anzahl dieser Übertragungsobjekte geben, die in kurzer Zeit erstellt werden und ihre Eigenschaften haben. Ich möchte die Verwendung von Reflektion vermeiden, gibt es Alternativen? Wenn ja, gibt es Beispielimplementierungen, die ich mir anschauen könnte?Verbesserung der Leistungsreflexion, welche Alternativen sollte ich berücksichtigen

Danke

+1

Warum möchten Sie die Reflexion vermeiden? –

Antwort

21

Verwenden Sie , um eine MethodInfo in einen stark typisierten Delegaten zu verwandeln. Dies kann die Leistung verbessern massiv. Ich habe eine blog post about this mit Beispielcode. Beachten Sie, dass dies nur hilfreich ist, wenn Sie dieselben Eigenschaften mehrmals festlegen müssen. Dies bedeutet im Wesentlichen, dass die Überprüfung des Typs einmal erfolgt, wenn Sie den Delegaten erstellen und nicht bei jedem Aufruf.

Marc GRA hat ein HyperPropertyDescriptor Projekt, das eine noch bessere Leistung erzielt, sondern stellt eine zusätzliche Abhängigkeit. Dieses Projekt wurde zum Ausgangspunkt für das modernere Fast Member (github). Im Allgemeinen würden Sie Fast Member über HyperProperty verwenden.

+0

Bekomme es dank http://msmvps.com/blogs/jon_skeet/archive/2008/08/09/making-reflection-fly-and-exploring-delegates.aspx – AndyMM

+0

Das ist so viel besser als versuchen, eine Dynamische Methode zu machen – JoshBerke

+0

Ich habe einige interessante Beispiele in .NET 4.0 mit DLR-Bäumen - hoffentlich für den Artikel ;-p –

0

Haben Sie mit Gewissheit festgestellt, dass Reflektion zu langsam ist? Obwohl die Reflexion in .NET nicht so schnell als statischen Code ist, ist es immer noch extrem schnell. Sie sollten den Code so einfach wie möglich schreiben - auch wenn dieser eine Reflektion verwendet - und nur dann zur Optimierung zurückkehren, wenn Sie Leistungsprobleme bemerken und diese für Ihre Verwendung der Reflexion isolieren. Die meiste Zeit werden Sie keine Probleme haben. Reflection wird in allen Arten von leistungssensitivem Code verwendet, z. B. ASP.NET MVC.

+0

Ich denke, was ich suche, ist die schnellstmögliche Implementierung. Ich suche auch Alternativen nur für die Due Diligence. Ich möchte nicht in eine Technik verwickelt werden, nur weil es mir vertraut ist, ohne nach Alternativen zu suchen. – AndyMM

0

Reflexion einen schlechten Ruf von Java bekam, wo sie (oder zumindest verwendet sehr langsam sein. Dies ist bei .net nicht der Fall, daher verstehe ich Ihre Einwände nicht. Auch stimme ich Rex zu, man kann nicht sagen, dass etwas schlechte Leistung hat, ohne tatsächlich zu messen.

+0

Ich habe nicht gesagt, es hatte schlechte Leistung, ich deutete es an! Witze beiseite bitte siehe Kommentar zu rex. – AndyMM

+0

Es hängt davon ab, was Sie mit "sehr langsam" meinen. Es kann sehr leicht immer noch ein Flaschenhals sein, wenn Sie es naiv verwenden ... aber mit etwas Arbeit (z. B. Delegate.CreateDelegate und dergleichen) kann es ziemlich nippy gemacht werden. –

2

Reflexion kann unglaublich schnell sein wenn Sie es richtig machen (nicht so schnell wie statische Code, natürlich).

Das Finden eines Property-Setters ist langsam. Der Aufruf eines Delegierten ist schnell.

Sie müssen Delegate Objekte für jeden Property-Setter für jeden DTO-Typ abrufen und zwischenspeichern. Das ist der langsame Teil, aber es ist ein einmaliger Erfolg. Dann können Sie Invoke jede der zwischengespeicherten Delegaten für die Property-Setter eines bestimmten DTO-Typs, übergeben Sie das DTO-Objekt und den neuen Eigenschaftswert, aber dieser Teil wird sehr schnell sein.

+1

Danke Gerechtigkeit Ich werde deine Idee versuchen. – AndyMM

5

In .NET 4.0 (Beta) können Sie dies mit den aktualisierten Ausdrucksbaumstrukturen unter Verwendung von Expression.Block und Expression.Assign tun - dann kompilieren Sie das zu einem typisierten Delegaten; Job erledigt.

In .NET 2.0 und oben (als Jon erwähnt) ist HyperDescriptor eine vernünftige Option - es als benutzerdefinierte PropertyDescriptor Implementierung funktioniert, so dass Sie Code wie:

// store this collection for optimum performance 
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(
    typeof(SomeType)); 
props["Name"].SetValue(obj, newName); 
props["DateOfBirth"].SetValue(obj, newDoB); 

Dies hat noch ein wenig Boxen, aber das ist nicht wirklich ein Engpass.

Verwandte Themen