Source Optimizer

lua-users home
wiki

Lua Source Optimizer 是一个优化 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 和带有 debug 库的堆栈级别的函数可能无法正确内联。这可能发生在访问任何全局变量时。

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

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

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

这可以按函数进行,也可以是文件中的更全局的默认设置。(请参阅 LuaFish 中的 luaanalyze,以获取建议的语法设计。)

更多详情请参阅 sourceoptimizer.mlua 的源代码。

局限性

警告:对于某些不常见的情况,例如内联函数使用 setfenv 或利用堆栈级别的 debug 函数(见上文),可能无法正常工作。getfenv/setfenv 问题在LuaFiveTwo中会不那么显著。

可能的应用

可能的扩展

作者

DavidManura


RecentChanges · preferences
编辑 · 历史
最后编辑于 2010 年 9 月 18 日下午 5:22 GMT (diff)