Reflexion-Performance - Erstellen Von Delegaten (Eigenschaften Von C#)
Ich habe performance-Probleme mit mit der spiegelung.
Also habe ich beschlossen zu erstellen Delegierten für die Eigenschaften meiner Objekte und so weit gekommen sind diese:
TestClass cwp = new TestClass();
var propertyInt = typeof(TestClass).GetProperties().Single(obj => obj.Name == "AnyValue");
var access = BuildGetAccessor(propertyInt.GetGetMethod());
var result = access(cwp);
static Func<object, object> BuildGetAccessor(MethodInfo method)
{
var obj = Expression.Parameter(typeof(object), "o");
Expression<Func<object, object>> expr =
Expression.Lambda<Func<object, object>>(
Expression.Convert(
Expression.Call(
Expression.Convert(obj, method.DeclaringType),
method),
typeof(object)),
obj);
return expr.Compile();
}
Die Ergebnisse waren sehr zufriedenstellend, etwa 30-40 mal schneller als die Verwendung der konventionellen Methode (PropertyInfo.GetValue (obj, null);
)
Das problem ist: Wie kann ich eine SetValue
einer Immobilie, die die gleiche Weise funktioniert? Leider bekommt Sie nicht Weg.
Ich bin dabei, weil ich nicht verwenden können, Methoden, mit <T>
aufgrund der Struktur der Anwendung.
- "Ich mache das so, weil ich kann nicht mit Methoden, die mit "< T >" aufgrund der Struktur der Anwendung" -- bedeutet das, dass Ihre NETFX-version < 2.0? Warum können Sie nicht verwenden, dass Generika in Ihrer Anwendung?
- Auch nicht, was das erstellen Delegierten für Ihre Immobilien zu tun haben, mit der Reflexion, und welches problem Sie versuchen zu lösen, mit der spiegelung?
- Die Delegierten haben die deutlich bessere Leistung und kann verwendet werden, dynamisch. Sie sind die bevorzugte option, wenn Sie brauchen, um verwenden der dynamischen Aufruf.
- klar nicht < 2.0 da er mit generics und Lambda-Ausdrücke selbst. Aber ich bin mit Ihnen. Was versuchst du hier zu tun ist, letztlich?
- Ja, ich kann (.NET 4.0), aber nicht gut wäre für alle, die der Logik meiner Anwendung. Und es würde viele änderungen zu machen. Vor allem die Kommunikation zwischen den WebServices, es gibt keine Stelle in meiner Anwendung, die gilt, "<T>" Methoden laden, speichern, aktualisieren, einfügen ...
- Ich würde vorschlagen, zu verwenden Fasterflect, eine umfassende Bibliothek, die macht der Reflexion viel schneller und einfacher zu verwenden an der Spitze. Sehen fasterflect.codeplex.com für details und Gebrauchsspuren. Gebaut mit DynamicMethod und IL-generation mit integrierten caching.
- Oder ähnlich: FastMember - immer wieder, DynamicMethod / IL, mit built-in-cache
- Vielen Dank für die Anregungen, ich suchte ein wenig über Bibliotheken. Aber die meisten erfordern viel code zur Implementierung und viele änderungen in meiner Anwendung. Wenn ich noch nicht bekommen, ausreichend Leistung. Ich werde hinter...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sollte diese Arbeit für Sie:
Verwendung:
Mit
TestClass
:Druckt:
Ich glaube, Sie wäre besser dran mit
CreateDelegate
konstruieren, wenn die Leistung der Schlüssel. Da Sie wissen, die Signatur der Methode, im Vorfeld, das hier ist nurGetGetMethod
undGetSetMethod
desPropertyInfo
erstellen, können Sie einen Delegaten ausführen der Methode mit der gleichen Signatur direkt. Ausdrücken wäre besser geeignet, wenn Sie brauchen, um zu bauen eine gewisse Logik (für die die Sie nicht haben eine Methode handle) an die Delegierten. Ich habe einige benchmarking auf verschiedenen Routen zu diesem problem:Ich würde, in deinem Fall schreiben:
So, jetzt rufen Sie:
Ist das nicht einfacher?? Geschrieben hatte, eine generische Klasse hier zu behandeln, die genaue Sache.
Verwendung von dynamischen Typen. Sie verwenden Reflexion unter der Haube, aber Sie sind viel schneller.
Ansonsten...
Es gibt Tonnen von kostenlosen schneller Reflexion Bibliotheken gibt, mit freizügigen Lizenzen. Ich würde link Sie, aber es gibt zu viele, und ich bin mir nicht sicher, welche passen würde Sie. Suchen Sie einfach codeplex etc. Wenn Sie etwas finden, Sie mögen, probieren Sie es aus.
Aber ja, vielleicht vor, dass, glaube wenn die Reflexion wirklich ist die Antwort. Oft gibt es andere Lösungen.
Edit: Wie Gewünscht...
http://geekswithblogs.net/SunnyCoder/archive/2009/06/26/c-4.0-dynamics-vs.-reflection.aspx
http://theburningmonk.com/2010/09/performance-test-dynamic-method-invocation-in-csharp-4/
http://www.mssoftwareconsulting.com/msswc/blog/post/C-40-and-dynamic-performance.aspx
Es ist allgemein bekannt, soweit ich das sagen kann.
dynamic foo = bar;
Dynamics ist ein großes Thema - wenn Sie beziehen sich auf GebäudeExpressionTree
Objekte, dann ja - das ist das, was Dynamik sind für. 🙂dynamic type
, und das ist das, was ich meinte. Das DLR ist soll für den dynamischen Aufruf von Methoden und Eigenschaften. Offenbar etwas, das ich nicht bis jetzt wissen, die DLR nutzt Ausdruck Bäume unter der Haube als auch (neben der Reflexion). Wenn Sie schauen Sie in die links oben, sehen Sie, dass das aufrufen einer Methode mit dynamischer Typ ist schneller, um mehrere Größenordnungen als mit MethodBase.Invoke. Es ist auch viel einfacher und präziser als das erstellen einer expression tree.dynamic
noch gar nicht existierte. Aber, ich bestreite nicht die Tatsache, dass das DLR ist nicht der Schnellste Weg, um eine Methode aufzurufen. Ich sage, es ist viel schneller als die Reflexion, und lächerlich einfach zu bedienen.