2010-12-06 8 views
9

Ich mache einige Post-Build-CIL Weberei, die CIL zu allen Methoden in einer Baugruppe (mit anderen Worten Tonnen von Methoden) hinzufügt. Jede Methode prüft, ob ein bestimmter Wert Null ist. Beispiel (C# Reflector'd Version von CIL-Code):Tatsächliche Leistung von Feldern vs. Eigenschaften

// CIL woven region start 
if (MyType.Something == null) { 
// ... some new stuff 
} 
// CIL woven region end 

Was ist die Auswirkung auf die Leistung von MyType.Something mit als Eigenschaft im Vergleich zu einem Feld? Ich weiß, dass ich gelesen habe, dass der C# -Compiler spezielle Optimierungen durchführt und es in diesem Fall keine Auswirkungen auf die Leistung geben sollte ... aber was ist mit dem direkten CIL-Code (kein C# -Compiler) ...? Oder ist es der JIT-Compiler, der diese Optimierungen ermöglicht (so dass direkter CIL-Code immer noch Vorteile bietet)?

Wird die Ausgabe von OpCode.Call für den Accessor der statischen Eigenschaft schlechter sein als die von Ldsfld (bedenken Sie, dass dies über Zehntausende von Aufrufen erfolgt, da jede Methode in der Assembly verwoben ist)?

Danke.

+0

könnten Sie erklären, warum haben Sie sich entschieden, das zu implementieren? – Andrey

+0

Implementieren was? – Jeff

Antwort

13

Bei der Entwicklung der Mathe-Bibliothek für SlimDX haben wir festgestellt, dass die Verwendung von Feldern für die Mitglieder der mathematischen Typen (wie X, Y, Z für einen Vector3) bei SP3-Frameworks unter pre.NET 3.5 eine unverhältnismäßige Leistung erbrachte über Eigenschaften erhöhen. Mit anderen Worten, der Unterschied war für kleine mathematische Funktionen bemerkbar, auf die Eigenschaften stark zugegriffen wurden.

Dies wurde seit .NET 3.5 SP1 verbessert (siehe JIT inling). Während ich glaube, dass die JIT davor noch kleine Methoden inline (Eigenschaften sind einfach nur Methoden), gibt es einen Fehler in den früheren Frameworks, die Inlining von Methoden verhindert, die Werttypen annehmen oder zurückgeben.

Beachten Sie, dass der Unterschied, wenn dort, immer noch ziemlich klein ist. Ich würde immer noch wählen, Eigenschaften in allen außer den leistungsfähigsten Fällen zu verwenden.

+0

Ok danke. Wir verwenden 3,5 SP1. Nur neugierig, da der Code ist CIL und nur sichtbar post build, was ist Ihr Grund für die Verwendung von Eigenschaften noch? – Jeff

+0

In Ihrem Fall weiß ich nicht, dass ich eine Eigenschaft verwenden würde.Im Allgemeinen ist die Rational-Behind-Eigenschaft Robustheit aus Sicht der Bibliothekskonstruktion und -wartung, aber das scheint hier nicht zu gelten. – MikeP

4

Der C# -Compiler wird dies nicht optimieren, nein - aber der JIT-Compiler kann in der Regel triviale (und nicht virtuelle) Eigenschaften enthalten, soweit mir bekannt ist.

Wie bei allen Leistungsfragen: Im Zweifelsfall Test!

+0

Ich bin mir nicht sicher, wie ich testen soll, ohne den "Beobachter" -Effekt zu erleiden, also habe ich gehofft, dass jemand von der Hand weiß. – Jeff

+2

@ JeffN825: Ich würde argumentieren, dass, wenn Sie den Test in Real-World-Code anwenden können und nicht in der Lage sein, einen Unterschied zu beobachten, dann ist das gut genug Beweise, dass jeder Unterschied unbedeutend ist :) –

2

Der Effekt ist in beiden Richtungen gering. Wenn Ihre Eigenschaften wie folgt aussehen:

public static SomeType PropertyName 
{ 
    get {return MyType.propertyName;} 
    set {MyType.propertyName = value;} 
} 

Es sollte wirklich ein sehr kleiner Unterschied sein. Der Jit-Compiler sollte die callMyType.set_Property in ein Feld laden, aber auch wenn es aufgrund eines Fehlers nicht möglich war. Ich würde persönlich auf der Seite der Vorsicht irren und bei den Property Settern und Gettern bleiben, da sich möglicherweise der Methodenkörper ändern könnte, und als Ergebnis könnte der rohe Feldzugriff/die Feldmutation nicht ausreichen.

Wenn Sie einen Test durchführen möchten, können Sie erzwingen, dass die ausgegebene Methode MethodImpl verwendet, die das Inlining oder die Optimierung deaktiviert. Und dann vergleichen Sie den Unterschied, ich bezweifle wirklich, dass es signifikant sein wird.