将值声明为本地值一次比每次声明本地值慢。

如何可能呢?这段代码:

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 循环是否有它们自己的本地变量?如果是,那么从当前块访问本地变量是否比从外部块访问本地变量更快?

点赞
用户1009479
用户1009479

一般来说,尽可能将变量声明为本地变量。是更好的编码风格,而且通常更加优化,就像这个例子所示的那样,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所在的位置)。这就回答了你的问题。

2016-05-19 15:54:20