将值声明为本地值一次比每次都将其声明为本地值慢
Declaring a value as local once is slower than declaring it local each time
这段代码怎么可能:
local t
for n = 0, 255 do
t = math.random(0, 255)
...
end
居然比这个慢?
for n = 0, 255 do
local t = math.random(0, 255)
...
end
由于我在 ...
部分访问了 t
不止一次,我想知道 for
循环是否有自己的一组局部变量?如果是,从当前块访问局部变量是否比从外部块访问局部变量更快?
一般情况下,尽可能将变量声明为local。是的,for
循环有自己的作用域。这是更好的编码风格,并且如本例所示,通常更优化。
让我们看看这两段代码生成了什么指令,luac -l
第一篇:
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
第二篇:
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
如你所见。第一部分有两个额外的说明。其中之一在循环内:
11 [3] MOVE 0 5
这样做是将寄存器 5
中的结果(具有 math.random
的结果)移动到寄存器 0
(这是变量 t
是)。这就回答了你的问题。
这段代码怎么可能:
local t
for n = 0, 255 do
t = math.random(0, 255)
...
end
居然比这个慢?
for n = 0, 255 do
local t = math.random(0, 255)
...
end
由于我在 ...
部分访问了 t
不止一次,我想知道 for
循环是否有自己的一组局部变量?如果是,从当前块访问局部变量是否比从外部块访问局部变量更快?
一般情况下,尽可能将变量声明为local。是的,for
循环有自己的作用域。这是更好的编码风格,并且如本例所示,通常更优化。
让我们看看这两段代码生成了什么指令,luac -l
第一篇:
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
第二篇:
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
如你所见。第一部分有两个额外的说明。其中之一在循环内:
11 [3] MOVE 0 5
这样做是将寄存器 5
中的结果(具有 math.random
的结果)移动到寄存器 0
(这是变量 t
是)。这就回答了你的问题。