我在LuaJIT工作,把我所有的库和诸如此类的东西存储在“foo”中,如下所示:
foo = {}; -- The only global variable
foo.print = {};
foo.print.say = function(msg) print(msg) end;
foo.print.say("test")
现在我想知道,是否会使用metatables并保持所有图书馆的本地帮助?或者没关系。我想到的是:
foo = {};
local libraries = {};
setmetatable(foo, {
__index = function(t, key)
return libraries[key];
end
});
-- A function to create a new library.
function foo.NewLibrary(name)
libraries[name] = {};
return libraries[name];
end;
local printLib = foo.NewLibrary("print");
printLib.say = function(msg) print(msg) end;
-- Other file:
foo.print.say("test")
我现在没有真正的基准测试工具,但是保留本地表中库的实际内容会提高性能吗?即使是最轻微的?
我希望我对此有所了解,基本上我想知道的是:性能方面的第二种方法更好吗?
如果有人可以链接/详细解释Lua中如何处理全局变量,这可以解释这一点也很好。
答案 0 :(得分:2)
现在没有真正的工具来对此进行基准测试
当然可以。
local start = os.clock()
for i=1,100000 do -- adjust iterations to taste
-- the thing you want to test
end
print(os.clock() - start)
凭借性能,您几乎总是希望进行基准测试。
是否会保持本地表中库的实际内容能够提高性能?
与第一个版本的代码相比?理论上没有。
你的第一个例子(剥离了不必要的瑕疵):
foo = {}
foo.print = {}
function foo.print.say(msg)
print(msg)
end
要获得打印功能,需要进行三次表查找:
foo
表
foo.print
表格中有“说”。你的第二个例子:
local libraries = {}
libraries.print = {}
function libraries.print.say(msg)
print(msg)
end
foo = {}
setmetatable(foo, {
__index = function(t, key)
return libraries[key];
end
});
要获得打印功能,现在需要进行五次表格查找以及其他额外工作:
foo
表
foo
是否有metatable,找到一个libraries
print
表
醇>
其中一些额外的工作是在C代码中完成的,所以它会比在Lua中实现的更快,但肯定会花费更多的时间。
使用上面显示的循环进行基准测试,第一个版本大约是香草Lua中第二个版本的两倍。在LuaJIT中,两者的速度完全相同。显然,在LuaJIT中,差异会在运行时得到优化(这非常令人印象深刻)。只是说明基准测试的重要性。
附注:Lua允许您提供__index
的表格,这将导致与您的代码等效的查找:
setmetatable(foo, { __index = function(t, key) return libraries[key] end } )
所以你可以写:
setmetatable(foo, { __index = libraries })
这也恰好更快。
答案 1 :(得分:1)
以下是我编写模块的方法:
-- foo.lua
local MyLib = {}
function MyLib.foo()
...
end
return MyLib
-- bar.lua
local MyLib = require("foo.lua")
MyLib.foo()
请注意,return MyLib
不在函数中。 require
捕获此返回值并将其用作库。这样,就没有全局变量。