Lua 编译器是否会优化局部变量?

3

目前的Lua编译器是否足够智能,可以优化掉仅用于代码清晰度的局部变量?

local top = x - y
local bottom = x + y
someCall(top, bottom)

手动内联是否更快?
someCall(x - y, x + y)

代码优化本身就是时间和空间的权衡,因为编译器通常内置于虚拟机中(参见load)。当然,你也可以制作一个不同的编译器,以便针对目标运行时虚拟机优化Lua字节码。 - Tom Blodget
1个回答

7

由于Lua通常会即时将源代码编译成字节码,因此它被设计为快速的一遍编译器。它确实会做一些常量折叠,但除此之外并没有太多优化。您通常可以通过执行luac -l -l -p file.lua并查看生成的(反汇编的)字节码来检查编译器的操作。

在您的情况下,Lua代码

function a( x, y )
  local top = x - y
  local bottom = x + y
  someCall(top, bottom)
end

function b( x, y )
  someCall(x - y, x + y)
end

当通过luac5.3 -l -l -p file.lua运行以下字节码清单时,会得到以下结果(省略了一些无关部分):

function <file.lua:1,5> (7 instructions at 0xcd7d30)
2 params, 7 slots, 1 upvalue, 4 locals, 1 constant, 0 functions
    1   [2] SUB         2 0 1
    2   [3] ADD         3 0 1
    3   [4] GETTABUP    4 0 -1  ; _ENV "someCall"
    4   [4] MOVE        5 2
    5   [4] MOVE        6 3
    6   [4] CALL        4 3 1
    7   [5] RETURN      0 1
constants (1) for 0xcd7d30:
    1   "someCall"
locals (4) for 0xcd7d30:
    0   x   1   8
    1   y   1   8
    2   top 2   8
    3   bottom  3   8
upvalues (1) for 0xcd7d30:
    0   _ENV    0   0

function <file.lua:7,9> (5 instructions at 0xcd7f10)
2 params, 5 slots, 1 upvalue, 2 locals, 1 constant, 0 functions
    1   [8] GETTABUP    2 0 -1  ; _ENV "someCall"
    2   [8] SUB         3 0 1
    3   [8] ADD         4 0 1
    4   [8] CALL        2 3 1
    5   [9] RETURN      0 1
constants (1) for 0xcd7f10:
    1   "someCall"
locals (2) for 0xcd7f10:
    0   x   1   6
    1   y   1   6
upvalues (1) for 0xcd7f10:
    0   _ENV    0   0

如您所见,第一个变体(a函数)有两个额外的MOVE指令和两个额外的局部变量。如果您对操作码的细节感兴趣,可以查看lopcodes.h中的OpCode枚举的注释。例如,OP_ADD的操作码格式为:
OP_ADD,/*       A B C   R(A) := RK(B) + RK(C)                           */

因此,上面的2 [3] ADD 3 0 1会将寄存器0和1(在这种情况下是本地变量xy)的值相加,并将结果存储在寄存器3中。它是该函数中的第二个操作码,相应的源代码位于第3行。


2
可以将luac的输出导入到luacexplain中。它会显示lopcodes.h中的伪代码,而不是让你自己去寻找。 - Niccolo M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接