38 Stimmen

Warum sind öffentliche Felder schneller als Eigenschaften?

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!

15voto

Reed Copsey Punkte 536986

Bearbeiten 2:

Ich hatte noch einen weiteren möglichen Gedanken dazu:

Sie haben erwähnt, dass Sie mit x64 arbeiten. Ich habe das gleiche Problem auf x86 getestet und die gleiche Leistung bei der Verwendung von Auto-Eigenschaften vs. Felder gesehen. Wenn Sie sich jedoch auf Connect und in der Mailingliste/im Forum umsehen, gibt es viele Hinweise auf die Tatsache, dass das JIT der x64 CLR eine andere Codebasis ist und ganz andere Leistungsmerkmale als das x86 JIT hat. Meine Vermutung ist, dass dies ein Punkt ist, an dem x64 noch hinterherhinkt.

Auch, FYI, die struct/method/etc Sache, die in .net 3.5sp1 behoben wurde, war auf der x86 Seite, und war die Tatsache, dass Methodenaufrufe, die structs als Parameter nahmen, nie auf x86 vor .net3.5sp1 inlined wurden. Das ist für diese Diskussion auf Ihrem System so gut wie irrelevant.


Bearbeiten 3:

Eine andere Sache: Warum XNA Felder verwendet. Ich war tatsächlich auf dem Game Fest, wo XNA angekündigt wurde. Rico Mariani hielt einen Vortrag, in dem er viele der Punkte ansprach, die auch in seinem Blog stehen. Es scheint, dass die XNA-Leute ähnliche Ideen hatten, als sie einige der Kernobjekte entwickelten. Siehe:

http://blogs.msdn.com/ricom/archive/2006/09/07/745085.aspx

Beachten Sie insbesondere Punkt 2.


Was die Frage betrifft, warum automatische Eigenschaften besser sind als öffentliche Felder:

Sie ermöglichen es Ihnen, die Implementierung in v2 Ihrer Klasse zu ändern und bei Bedarf Logik in die Get/Set-Routinen der Eigenschaften einzufügen, ohne die Schnittstelle zu Ihren Endbenutzern zu ändern. Dies kann sich erheblich auf Ihre Fähigkeit auswirken, Ihre Bibliothek und Ihren Code im Laufe der Zeit zu pflegen.

---- Aus dem ursprünglichen Beitrag - aber es stellte sich heraus, dass dies nicht das Problem war--------

Haben Sie einen Release-Build ausgeführt? außerhalb von VS? Das kann eine Erklärung dafür sein, warum die Dinge nicht optimiert werden. Wenn Sie in VS arbeiten, sogar in einem optimierten Release-Build, deaktiviert der VS-Host-Prozess oft viele Funktionen des JIT. Dies kann dazu führen, dass sich die Leistungsbenchmarks ändern.

5voto

JaredPar Punkte 699699

Sie sollten diesen Artikel von Vance lesen. Er geht im Detail darauf ein, warum Methoden nicht immer vom JIT'er inlined werden, auch wenn es völlig offensichtlich aussieht, dass sie es sein sollten.

http://blogs.msdn.com/vancem/archive/2008/08/19/to-inline-or-not-to-inline-that-is-the-question.aspx

3voto

FerranB Punkte 33783
  • Öffentliche Felder sind direkte Zuweisungen
  • Eigenschaften sind Methoden, dann mehr Code, unbedeutend, aber mehr.

3voto

Michael Punkte 52790

XNA muss auf die XBox 360 abzielen, und das JIT im .NET Compact Framework ist nicht so ausgereift wie sein Desktop-Pendant. Der .NET CF JIT'er wird keine Eigenschaftsmethoden einbinden.

3voto

tvanfosson Punkte 506878

Der Zugriff auf ein Feld ist nur ein Speicherverweis, während die Verwendung einer Eigenschaft den Aufruf einer Methode bedeutet und den Overhead für den Funktionsaufruf einschließt. Der Grund für die Verwendung von Eigenschaften anstelle von Feldern besteht darin, Ihren Code vor Änderungen zu schützen und eine bessere Granularität beim Zugriff zu gewährleisten. Da Sie Ihr Feld nicht direkt offenlegen, haben Sie eine bessere Kontrolle darüber, wie der Zugriff erfolgt. Bei der Verwendung von automatischen Feldern erhalten Sie das typische Getter/Setter-Verhalten, haben aber die Möglichkeit, dieses zu ändern, ohne dass sich die Änderungen auf andere Teile des Codes ausbreiten müssen.

Nehmen wir an, Sie möchten Ihren Code so ändern, dass der Zugriff auf ein Feld durch die Rolle des aktuellen Benutzers gesteuert wird. Hätten Sie das Feld öffentlich zugänglich gemacht, müssten Sie jeden Teil des Codes, der auf das Feld zugreift, ändern. Wenn Sie es über eine Eigenschaft freilegen, können Sie den Code der Eigenschaft ändern, um die neue Anforderung hinzuzufügen aber nicht zu unnötigen Änderungen am Code führt, der darauf zugreift .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X