源代码优化器

lua-users home
wiki

Lua 源代码优化器是一个工具,它可以对 Lua 源代码进行一些优化,主要通过 [内联函数]

描述

内联是部分求值的一种形式 [1]

代码

代码需要 [Metalua 0.5](开发分支)。

它包含以下文件

快速入门

Download tar file from http://github.com/fab13n/metalua/tree/0.5-branch .

tar xzvf fab13n-metalua-28e8e1037ab33d96c123667f4c3fc94b5aca83bc.tar.gz
mv fab13n-metalua-28e8e1037ab33d96c123667f4c3fc94b5aca83bc metalua
cd metalua && make

Download sourceoptimizer.mlua and place in metalua/build/lib/dmlib .
Download sourceoptimize.lua and place in metalua/ .
Download fib.lua example and place in metalua/ .

./build/bin/metalua sourceoptimize.lua fib.lua
# or
./build/bin/metalua sourceoptimize.lua fib.lua  | lua -

示例

这是一个基本示例

-- input:
local y=-1
local function square(x) return x*x end
local function g(x) return x >= 0 and square(square(x))+1 or 1 end
while (function() y = g(y)^(1/4) return y < 2 end)() do
  print(y)
end

-- output:
local y = - 1
while 1 do
   local __v13x = y
   local __v10 = 0 <= __v13x
   if __v10 then
      local __v12x = __v13x
      local __v14x = __v12x * __v12x
      __v10 = __v14x * __v14x + 1
   end
   local __v11 = __v10
   if not __v11 then
      __v11 = 1
   end
   y = __v11 ^ (1 / 4)
   if not (y < 2) then
      break
   end
   print (y)
end

下面是一些 Lua 示例的内联示例(在函数名前添加“local”,这是内联所必需的)

功能说明

代码将内联立即求值的匿名函数

x=(function(x) return x*x end)(y())
--> local __v1x=y() x=__v1x*__v1x

以及“常量”的局部函数(函数变量从不修改)

local function square(x) return x*x end; x=square(y())
--> local __v1x=y() x=__v1x*__v1x

它消除了无用函数,例如完全内联的函数(如上所述)。它正确地执行转换以将表达式转换为语句

x = y or (function(x)z=1 return x*x end)(w)
--> local __v2=y if not __v2 then local __v1x=w z=1 __v2=__v1x*__v1x end x=__v2

if (function()x=x+1 return x end)() then f()
elseif (function()y=y+1 return y end)() then g()
else h() end
--> x=x+1 if x then f()else y=y+1 if y then g()else h()end end

使用setfenv和调试库的堆栈级别的函数可能无法正确内联。这可能发生在访问任何全局变量时

local function f() local _ = x end
f()

理论上我们不应该内联上面的函数,因为访问全局变量x“可能”会触发全局环境上的元表,进而可能改变f的环境,因此内联f会改变f调用者的环境。(在 LuaFiveTwo 中,环境将不再是一个问题,但一些调试函数仍然使用堆栈级别。)理想情况下,翻译器应该扩展以支持 Lua 注释中的pragma,这些pragma 定义了我们希望内联的程度

--!inline
local function f() local _ = x end
f()

这可以在每个函数的基础上进行,也可以是文件中更全局的默认设置。(有关建议的语法设计,请参阅 LuaFish 中的 luaanalyze。)

有关更多详细信息,请参阅 sourceoptimizer.mlua 的源代码。

限制

警告:对于内联函数使用 setfenv 或利用堆栈级别的调试函数的奇特情况,可能无法正常工作(见上文)。getfenv/setfenv 问题在 LuaFiveTwo 中将不那么重要。

可能的应用

可能的扩展

作者

DavidManura


最近更改 · 偏好设置
编辑 · 历史记录
最后编辑于 2010 年 9 月 18 日下午 11:22 GMT (差异)