Lokale Variablen in Schleifen?
-
Einen wunderschönen guten Abend
Ich frage mich gerade, ob es wohl einen Unterschied macht, ob ich:int a; for(int i=0;i<10000;++i){ a = 0; for(int k=0;k<1000;++k) a += k; }und
for(int i=0;i<10000;++i){ int a = 0; for(int k=0;k<1000;++k) a += k; }Also konkret, ob es einen Performanzunterschied macht, ob ich so eine Variable innerhalb einer Schleife deklariere oder nicht. Ich könnte mir vorstellen, dass der Kompiler das dann doch ausserhalb der Schleife deklariert?
Mfg Samuel
-
Ich würde sagen, dass der Compiler eh den gleichen Maschinencode generiert. Vielleicht interessiert dich ja wie der stack organisiert ist: http://www.cs.utk.edu/~plank/plank/classes/cs360/360/notes/Assembler1/lecture.html
-
@jesus was black: Dein Link funktioniert nicht
Und ja: Wenn überhaupt, dann ändert sich bloß die Position von a auf dem Stack. Bei der Definition von primitiven Typen wie int passiert ja nichts im Prozessor, das ist einfach nur eine Speicherzelle die benutzt wird. Bei Klassen mit komplexem Konstruktor/Destruktor sieht die Sache natürlich ganz anders aus, aber das sollte wohl klar sein.
-
Naja, ich frage mich, ob er den Stackzeiger erst dann anpasst, wenn ich die variable definiere => Also sub esp,0h04, oder ob er sämtliche lokalen Variable innerhalb einer Methode oder Funktion nimmt, deren Speicherbedarf zusammenzählt und schliesslich ein einziges mal ein sub macht?
-
Oh, jetzt bin ich baff: g++ ohne alle Optimierungen erzeugt tatsächlich anderen Maschinencode. Der relevante Abschnitt:
Variante 1:
call ___main movl $0, -4(%ebp) movl $0, -8(%ebp) L2: cmpl $9999, -8(%ebp) jg L3 movl $0, -12(%ebp) L5: cmpl $999, -12(%ebp) jg L4 movl -12(%ebp), %eax leal -4(%ebp), %edx addl %eax, (%edx) leal -12(%ebp), %eax incl (%eax) jmp L5 L4: leal -8(%ebp), %eax incl (%eax) jmp L2 L3: movl $0, %eax leave retUnd Variante 2:
call ___main movl $0, -4(%ebp) L2: cmpl $9999, -4(%ebp) jg L3 movl $0, -8(%ebp) movl $0, -12(%ebp) L5: cmpl $999, -12(%ebp) jg L4 movl -12(%ebp), %eax leal -8(%ebp), %edx addl %eax, (%edx) leal -12(%ebp), %eax incl (%eax) jmp L5 L4: leal -4(%ebp), %eax incl (%eax) jmp L2 L3: movl $0, %eax leave retDer Unterschied ist, dass die movl Anweisung aus Zeile 3 der ersten Variante ein paar zeilen nach unten gerückt wird und somit innerhalb der Schleife liegt die sich von Label L2 bis L3 erstreckt. Das heißt, dass diese Anweisung tatsächlich 10.000 Mal ausgeführt wird anstatt 1x. Soviel also zu vorschnellen Verlautbarungen, dass es keinen Unterschied macht.
-
Ohne alle Optimierungen wundert mich garnicht dass anderer Code rauskommt.
Ohne alle Optimierungen interessiert aber keinen. Also zumindest mich nicht.
-
hustbaer schrieb:
Ohne alle Optimierungen interessiert aber keinen. Also zumindest mich nicht.
Mich auch nicht.