Ich habe in XNA herumgestöbert und gesehen, dass die Vector3
Klasse verwendet öffentliche Felder anstelle von Eigenschaften. Ich habe einen kurzen Benchmark durchgeführt und festgestellt, dass für eine struct
ist der Unterschied ziemlich dramatisch (das 100-Millionen-malige Hinzufügen von zwei Vektoren dauerte 2,0 Sekunden mit Eigenschaften und 1,4 Sekunden mit Feldern). Bei einem Referenztyp scheint der Unterschied nicht so groß zu sein, aber er ist da.
Und warum ist das so? Ich weiß, dass eine Eigenschaft kompiliert wird in get_X
y set_X
Methoden, was zu einem Overhead beim Methodenaufruf führen würde. Sind diese einfachen Getters/Setters jedoch nicht siempre von der JIT in-lined werden? Ich weiß, dass man nicht garantieren kann, was das JIT tut, aber das steht doch ziemlich weit oben auf der Liste der Wahrscheinlichkeiten? Was unterscheidet sonst noch ein öffentliches Feld von einer Eigenschaft auf Maschinenebene?
Und eine Sache, die ich mich gefragt habe: Wie ist eine automatisch implementierte Eigenschaft ( public int Foo { get; set; }
) "bessere" OO-Konstruktion als ein öffentliches Feld? Oder besser gesagt: Wie sind diese beiden verschiedene ? Ich weiß, dass es eine Eigenschaft ist einfacher mit Reflexion, aber etwas anderes? Ich wette, die Antwort auf beide Fragen ist die gleiche.
BTW: Ich verwende .NET 3.5 SP1, die ich glaube, Probleme behoben, wo Methoden mit structs (oder Methoden von structs, ich bin mir nicht sicher) waren nicht in-lined, also ist es das nicht. Ich denke, ich benutze es zumindest, es ist sicherlich installiert, aber dann wieder, ich bin mit Vista 64-Bit mit SP1, die DX10.1 außer, dass ich nicht DX10.1 haben sollte
Außerdem: Ja, ich habe einen Release-Build laufen lassen :)
EDIT : Ich weiß die schnellen Antworten zu schätzen, aber ich habe angegeben, dass ich faire Ich weiß, dass ein Eigenschaftszugriff ein Methodenaufruf ist, aber ich weiß nicht, warum die vermutlich eingebettete Methode langsamer ist als ein direkter Feldzugriff.
EDIT 2 : Also habe ich eine weitere struct
die explizite GetX()-Methoden verwenden (oh, wie ich meine Java-Tage nicht vermisse überhaupt ) und das funktionierte genauso, egal ob ich das In-Lining deaktiviert habe (durch [MethodImplAttribute(MethodImplOptions.NoInlining)]
) oder nicht, so dass die Schlussfolgerung: nicht statische Methoden sind offenbar nie inlined, auch nicht auf structs.
Ich dachte, es gäbe Ausnahmen, bei denen das JIT den Aufruf der virtuellen Methode wegoptmieren könnte. Warum kann das nicht bei Structs passieren, die keine Vererbung kennen und somit kann ein Methodenaufruf nur auf eine mögliche Methode zeigen, richtig? Oder ist das so, weil man eine Schnittstelle darauf implementieren kann?
Dies ist eine Art von Schande, da es wirklich machen mich über die Verwendung von Eigenschaften auf Performance-kritischen Sachen denken, noch mit Feldern macht mich schmutzig und ich könnte genauso gut schreiben, was ich in C tun.
EDIT 3 : Ich fand este über genau dasselbe Thema zu posten. Seine Schlussfolgerung ist, dass der Eigenschaftsaufruf wegoptimiert wurde. Ich könnte auch geschworen haben, dass ich viele Male gelesen habe, dass einfache Getter/Setter-Eigenschaften in-lined erhalten, obwohl sie callvirt
in der IL. Werde ich also wahnsinnig?
EDIT 4 : Reed Copsey hat die Antwort in einem Kommentar unten veröffentlicht:
Re: Edit3 - siehe meinen aktualisierten Kommentar: Ich glaube, das ist ein Problem zwischen x86 JIT und x64 JIT. Das JIT in x64 ist nicht so ausgereift. Ich erwarte, dass MS dies schnell verbessern wird, da jeden Tag mehr 64-Bit-Systeme in Betrieb genommen werden. - Reed Copsey
Und meine Antwort auf seine Antwort:
Danke, das ist die Antwort! Ich habe versucht, ein x86-Build zu erzwingen, und alle Methoden sind gleich schnell, und viel schneller als die x64. Dies ist sehr schockierend für mich eigentlich, ich hatte keine Ahnung, ich war in der Steinzeit auf meinem 64-Bit-OS leben. Ich werde Ihren Kommentar in meine Antwort einfügen, damit er besser hervorsticht. - JulianR
Vielen Dank an alle!