Ganzzahlige Felder / Eigenschaften in einem Konstruktor auf Null setzen

7

Während einer kürzlich durchgeführten Code-Überprüfung schlug ein Kollege vor, dass bei Klassen mit 4 int-Eigenschaften die Zuweisung von jeweils null im Konstruktor zu einer Leistungseinbuße führen würde.

Zum Beispiel

%Vor%

Sein Punkt war, dass dies überflüssig ist, da sie standardmäßig auf Null gesetzt werden und Sie Overhead einführen, indem Sie im Wesentlichen die gleiche Aufgabe zweimal ausführen. Mein Punkt war, dass der Leistungshit vernachlässigbar wäre, wenn überhaupt einer vorhanden wäre, und dies ist besser lesbar (es gibt mehrere Konstruktoren), da die Absicht des Zustands des Objekts nach dem Aufruf dieses Konstruktors sehr klar ist.

Was denkst du? Gibt es einen Leistungsgewinn, den es wert ist, sich hier um etwas zu kümmern?

    
Peter Kelly 03.11.2010, 16:51
quelle

8 Antworten

5

Ich glaube nicht, dass es sich um dieselbe Operation handelt, und ist ein Leistungsunterschied. Hier ist ein Microbenchmark, um es zu zeigen:

%Vor%

Ergebnisse:

%Vor%

Würde mich das den Code ändern? Absolut nicht. Schreiben Sie zuerst den lesenswertesten Code. Wenn bei der Zuweisung besser lesbar ist, behalten Sie die Zuweisung dort bei. Auch wenn ein Microbenchmark zeigt, dass es Kosten verursacht, sind das im Zusammenhang mit echten Arbeiten immer noch geringe Kosten. Auch wenn die proportionale Differenz hoch ist, erzeugt sie immer noch eine Milliarde Instanzen in 8 Sekunden auf der "langsamen" Route. Meine Vermutung ist, dass es eine Art Optimierung für vollständig leere Konstruktoren gibt, die direkt an den vollständig leeren object() -Konstruktor verkettet sind. Der Unterschied zwischen der Zuweisung zu zwei Feldern und der Zuweisung zu einem Feld ist viel kleiner.

Wenn der Compiler es nicht optimieren kann, bedenken Sie, dass ein Basiskonstruktor den Wert durch Reflexion oder vielleicht einen Aufruf einer virtuellen Methode ändern könnte. Der Compiler könnte möglicherweise diese bemerken, aber es scheint eine seltsame Optimierung zu sein.

    
Jon Skeet 03.11.2010, 17:02
quelle
6

Nein, ist es nicht. Der Compiler wird diese Operationen optimieren; Die gleiche Aufgabe wird nicht zweimal ausgeführt. Dein Kollege hat Unrecht.

[Edit basierend auf der Eingabe des immer ausgezeichneten Jon Skeet]

Der Compiler SOLLTE die Operationen optimieren, aber anscheinend sind sie nicht vollständig optimiert; Der Optimierungsgewinn ist jedoch völlig vernachlässigbar, und der Vorteil einer so expliziten Zuweisung ist gut. Ihr Kollege mag vielleicht nicht völlig falsch liegen, aber sie konzentrieren sich auf eine völlig triviale Optimierung.

    
Paul Sonier 03.11.2010 16:53
quelle
4

Nach meinem Verständnis wird der Speicher von Objekten mit einem einfachen und sehr schnellen Speicherlöschung gelöscht. Diese expliziten Zuweisungen erfordern jedoch zusätzliche IL. In der Tat werden einige Tools erkennen Sie den Standardwert (in einem Feld Initialisierer) und raten davon ab.

Also würde ich sagen: Tu das nicht - es ist möglicherweise marginal langsamer. Aber nicht viel. Kurz gesagt, ich denke, dein Freund hat Recht.

Leider bin ich gerade auf einem mobilen Gerät, ohne die richtigen Werkzeuge, um es zu beweisen.

    
Marc Gravell 03.11.2010 16:56
quelle
3

Sie sollten sich auf die Code-Klarheit konzentrieren, das ist das Wichtigste. Wenn die Leistung zu einem Problem wird, messen Sie die Leistung, und sehen Sie, was Ihre Engpässe sind, und verbessern Sie diese. Es lohnt sich nicht, so viel Zeit mit der Sorge um die Leistung zu verbringen, wenn es leichter ist, Code zu verstehen.

    
McKay 03.11.2010 16:56
quelle
1

Sie können sie direkt als Felder initialisieren:

%Vor%

Und ist auch klar.

    
Liviu M. 03.11.2010 16:56
quelle
1

Die wichtigere Frage ist: Gibt es wirklich einen Lesbarkeitsgewinn? Wenn die Personen, die den Code verwalten, bereits wissen, dass Ints null zugewiesen sind, ist dies nur ein weiterer Code, den sie analysieren müssen. Vielleicht wäre der Code sauberer ohne Linien, die nichts tun.

    
Jonny Cundall 03.11.2010 17:02
quelle
1

Tatsächlich würde ich die Zuweisung im Konstruktor verwenden, nur zur besseren Lesbarkeit und um die Absicht "Ich habe nicht vergessen, diese zu initialisieren" zu markieren. Sich auf Standardverhalten zu verlassen, tendiert dazu, andere Entwickler zu verwirren.

    
nothrow 03.11.2010 17:03
quelle
0

Ich denke nicht, dass Sie sich um den Performance-Hit kümmern sollten, normalerweise gibt es viele andere Orte, an denen das Programm optimiert werden kann. Auf der anderen Seite sehe ich keinen Gewinn durch die Angabe dieser Werte im Konstruktor, da sie sowieso auf 0 gesetzt werden.

    
Andrew Bezzub 03.11.2010 16:55
quelle

Tags und Links