2016-05-19 7 views
5

lokale erklären Wie ist es möglich, dass dieses Stück Code:Deklarieren Wert als einmal vor Ort ist langsamer als es jedes Mal

local t 
for n = 0, 255 do 
    t = math.random(0, 255) 
    ... 
end 

Ist eigentlich langsamer als diese?

for n = 0, 255 do 
    local t = math.random(0, 255) 
    ... 
end 

Da ich t bin mehr Zugriff als einmal in dem ... Teil, frage ich mich, tun for Schleifen ihre eigene Reihe von lokalen Variablen haben? Wenn ja, greift der Zugriff auf eine lokale Variable vom aktuellen Block schneller ab als auf einen vom äußeren Block?

Antwort

7

Im Allgemeinen deklarieren Variablen wie lokalen als möglich. Und ja, for Schleife macht seinen eigenen Umfang. Es ist der bessere Codierungsstil und, wie dieses Beispiel zeigt, normalerweise besser optimiert.

Mal sehen, was Anweisungen die beiden Teile des Codes generieren, mit luac -l

Das erste Stück:

main <t.lua:0,0> (13 instructions at 00000000005e8260) 
0+ params, 8 slots, 1 upvalue, 5 locals, 5 constants, 0 functions 
     1  [1]  LOADNIL   0 0 
     2  [2]  LOADK   1 -1 ; 0 
     3  [2]  LOADK   2 -2 ; 255 
     4  [2]  LOADK   3 -3 ; 1 
     5  [2]  FORPREP   1 6  ; to 12 
     6  [3]  GETTABUP  5 0 -4 ; _ENV "math" 
     7  [3]  GETTABLE  5 5 -5 ; "random" 
     8  [3]  LOADK   6 -1 ; 0 
     9  [3]  LOADK   7 -2 ; 255 
     10  [3]  CALL   5 3 2 
     11  [3]  MOVE   0 5 
     12  [2]  FORLOOP   1 -7 ; to 6 
     13  [4]  RETURN   0 1 

Das zweite Stück:

main <t.lua:0,0> (11 instructions at 0000000000538260) 
0+ params, 7 slots, 1 upvalue, 5 locals, 5 constants, 0 functions 
     1  [1]  LOADK   0 -1 ; 0 
     2  [1]  LOADK   1 -2 ; 255 
     3  [1]  LOADK   2 -3 ; 1 
     4  [1]  FORPREP   0 5  ; to 10 
     5  [2]  GETTABUP  4 0 -4 ; _ENV "math" 
     6  [2]  GETTABLE  4 4 -5 ; "random" 
     7  [2]  LOADK   5 -1 ; 0 
     8  [2]  LOADK   6 -2 ; 255 
     9  [2]  CALL   4 3 2 
     10  [1]  FORLOOP   0 -6 ; to 5 
     11  [3]  RETURN   0 1 

Wie Sie sehen können. Das erste Stück hat zwei zusätzliche Anweisungen. Einer von ihnen ist in der Schleife.

 11  [3]  MOVE   0 5 

Was das bedeutet ist das Ergebnis in das Register 5 (die das Ergebnis der math.random hat sich zu bewegen, in das Register 0 (das ist, wo die Variable t ist) und

+0

Ok, also haben for-Schleifen ihren eigenen Gültigkeitsbereich, und der Zugriff auf eine lokale Variable aus dem äußeren Bereich ist langsamer, aber greift auf eine lokale Variable aus dem äußeren Bereich langsamer zu als auf eine globale Variable zuzugreifen? – user6245072

+0

I heißt es, ist es im obigen Code lebensfähig, 'local rand = math random' außerhalb der Schleife zu deklarieren und dann' rand' innerhalb der Schleife zu nennen? – user6245072

+0

@ user6245072 Die Antwort ist ja. Wenn die Schleife lang ist, hat die Zuweisung der Funktion an eine lokale Variable außerhalb der Schleife eine bessere Leistung. Kapitel 2 von [* Lua Programming Gems *] (http://www.lua.org/gems/) spricht ausführlich darüber. –