lua - 全局变量很糟糕,这会以任何方式提高性能吗?

标签 lua luajit

我正在 LuaJIT 中工作,并将所有库和其他内容存储在“foo”中,如下所示:

foo = {}; -- The only global variable
foo.print = {};
foo.print.say = function(msg) print(msg) end;
foo.print.say("test")

现在我想知道,使用元表并将所有库保留在本地是否有帮助?或者说没关系。我想到的是这样的:

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 中如何处理全局变量的详细解释,这也可以解释这一点,那就太好了。

最佳答案

don't really have the tools to benchmark this right now

当然可以。

local start = os.clock()
for i=1,100000 do -- adjust iterations to taste
    -- the thing you want to test
end
print(os.clock() - start)

对于性能,您几乎总是想要进行基准测试。

would keeping the actual contents of the libraries in a local table increase performance at all?

与第一个版本的代码相比?理论上不会。

您的第一个示例(剔除不必要的多余内容):

foo = {}
foo.print = {}
function foo.print.say(msg)
    print(msg)
end

要获得打印功能,需要进行三个表查找:

  1. 索引 _ENV 为“foo”
  2. 使用“print”索引 foo
  3. 使用“say”索引 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
});

要实现打印功能,现在需要进行五次表查找以及其他额外工作:

  1. 索引 _ENV 为“foo”
  2. 使用“print”索引 foo
  3. Lua 发现结果为 nil,检查 foo 是否有元表,找到一个
  4. 使用“__index”索引元表
  5. 检查结果是表还是函数,Lua 发现它是一个函数,所以用 key 调用它
  6. 使用“print”索引
  7. 使用“say”为 print 表建立索引

其中一些额外工作是在 C 代码中完成的,因此比全部在 Lua 中实现要快,但肯定会花费更多时间。

使用我上面展示的循环进行基准测试,第一个版本的速度大约是普通 Lua 中第二个版本的两倍。在LuaJIT中,两者的速度完全相同。显然,差异在 LuaJIT 中的运行时得到了优化(这非常令人印象深刻)。只是为了展示基准测试的重要性。


旁注:Lua 允许您为 __index 提供一个表,这将导致与您的代码等效的查找:

setmetatable(foo, { __index = function(t, key) return libraries[key] end } )

所以你可以写:

setmetatable(foo, { __index = libraries })

这也恰好快得多。

关于lua - 全局变量很糟糕,这会以任何方式提高性能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14881331/

相关文章:

c - Lua:编译一个包含所有依赖的脚本

multithreading - Tir 与其他 Lua Web 框架相比如何?

Lua 需要 block 环境

lua - Torch,为什么我的人工神经网络总是预测为零?

c - 如何使用ImageMagick C API的MagickGetImageHistogram

c - 如何用 LuaJIT 定义 C 函数?

c - Luajit FFI 直接取消引用不需要转换的值的语义

c++ - 如何静态构建和链接 LuaJIT (VS 2013)

performance - Lua:__index 作为函数与作为表的性能

loops - Lua 中的 "in"关键字有什么作用?