2017-02-23 4 views
0

Angenommen, ich habe die folgenden Code-Schnipselgibt es eine Leistungseinbuße, um die Objektdeklaration in eine Schleife zu setzen?

for (i = 1..100000) { 
    String s = make_some_string(i); // this function depends on `i` only 
    output_this_result(s); 
} 

Würde, die einen Unterschied machen, wenn die Erklärung von String s außerhalb der Schleife bewegt wird? Ich denke, der Compiler ist schlau genug, in jeder Schleife kein String-Objekt zu konstruieren und zu zerstören. Aber was wäre, wenn es eine komplizierte object anstelle einer string wäre?

+4

Testen Sie es. Sehen Sie sich die generierte ASM an. –

+0

Ich denke, Compiler ist schlau genug, aber muss getestet werden. –

+4

Offenbar wird eine neue Zeichenkette erzeugt und von 'make_some_string()' zugewiesen und später bei jeder Iteration zerstört. Haben Sie versucht, den Unterschied beider Versuche zu messen? Was hast du beobachtet? – moooeeeep

Antwort

1

Gibt es eine Leistungseinbuße, um die Objektdeklaration in eine Schleife zu setzen?

Es kann sein. Dies kann vom Typ des Objekts und den vom Compiler ausgeführten Optimierungen abhängen. Es hängt auch davon ab, was make_some_string zurückgibt (ist die String durch Kopie oder Konvertierung erstellt?) Und möglicherweise, ob make_some_string für den Compiler sichtbar ist (ist es in der gleichen Übersetzungseinheit definiert?).

Wenn Sie das Objekt im Inneren deklarieren, wird es am Anfang jeder Iteration erstellt und am Ende zerstört. Das Aufrufen eines Konstruktors und eines Destruktors ist möglicherweise langsamer als der Aufruf von Konstruktoren und Destruktoren. Die Aufrufe können nur dann weg optimiert werden, wenn sie keine Nebenwirkungen haben und ihre Implementierung für den Compiler sichtbar ist.

0

Sie verpassen die dritte Option, die wahrscheinlich effizienter ist, wenn Sie nur fragen, ob der String in der Schleife oder außerhalb davon deklariert werden soll.

Bedenken Sie:

for (i = 1..100000) { 
    output_this_result(make_some_string(i)); // Depend on `i` only 
} 

von s vollständig zu entfernen, Sie müssen sich nicht entscheiden, wo Sie es erklären würde. Dies erfordert natürlich, dass output_this_result keine String-Referenz nimmt und sie modifiziert, sondern den Namen gibt, der logisch erscheint. Und ich bezweifle, dass jeder Compiler schlechter Code als die Alternative generiert.

(Die For-Loop-Syntax sieht nicht wie C++ aus, war aber Teil der Frage.)

Verwandte Themen