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

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 是)。这就回答了你的问题。