3

我有一大段我希望能够(有选择地)忽略的 lua 代码。我没有不读它的选项,有时我希望它被处理,有时不是,所以我不能把它注释掉(也就是说,有一大堆代码块,我要么可以选择不阅读全部阅读。我想出了两种方法来实现它(可能还有更多——我是个初学者):要么将代码包含在一个函数中,然后调用或不调用该函数(一旦我确定我是通过了我将调用该函数的点,我可以将其设置nil为释放内存)或将代码包含在if ... end堵塞。前者有一些优势,因为有几个这样的块,并且使用前一种方法可以使一个块更容易加载另一个块,即使主程序没有请求它,但后者似乎更有效。但是,了解不多,不知道效率节省是否值得。

那么有多少效率是:

if false then
    -- a few hundred lines
end

throwaway = function ()
    -- a few hundred lines
end
throwaway = nil  -- to ensure that both methods leave me in the same state after garbage collection

?

如果它很大程度上取决于 lua 实现,那么“几百行”需要多大才能可靠地发现差异,以及它应该包括什么样的东西才能最好地测试(块的主要用途是定义一个加载可能有用的功能)?

4

4 回答 4

4

Lua 不够聪明,无法转储函数的代码,因此您不会节省任何内存。

就速度而言,您谈论的是不同的纳秒,每次程序执行都会发生一次。担心这一点会损害您的效率,这与实际性能几乎无关。编写您认为最清楚地表达您的意图的代码,而不是试图变得聪明。如果您遇到性能问题,那么距离这个决定还有一百万英里。

如果您想节省内存,这在移动平台上是可以理解的,您可以将条件代码放在它自己的模块中,并且根本不需要加载它(如果您的框架支持它;例如 MOAI 支持,Corona 不支持) .

于 2012-07-30T16:44:16.973 回答
2

如果确实有很多未使用的代码,您可以将其定义为字符串的集合,并loadstring()在需要时使用它。将函数存储为字符串将减少初始编译时间,但是在大多数函数中,字符串表示可能比其编译形式占用更多内存,并且编译时保存的内容在几千行之前可能并不重要......只是说。

如果将此代码放在一个表中,则可以通过元表透明地编译它,以便对重复调用的性能影响最小。

示例代码

local code_uncompiled = {
   f = [=[
      local x, y = ...;
      return x+y;
   ]=]
}
code = setmetatable({}, {
   __index = function(self, k)
      self[k] = assert(loadstring(code_uncompiled[k]));
      return self[k];
   end
});

local ff = code.f; -- code of x gets compiled here
ff = code.f; -- no compilation here
for i=1, 1000 do
   print( ff(2*i, -i) ); -- no compilation here either
   print( code.f(2*i, -i) ); -- no compile either, but table access (slower)
end

它的美妙之处在于它可以根据需要进行编译,您不必再浪费其他想法,就像将函数存储在表中一样,并且具有很大的灵活性。

此解决方案的另一个优点是,当动态加载的代码量失控时,您可以透明地更改它以通过元表的 __index 函数按需从外部文件加载代码。此外,您可以通过使用“真实”函数填充“代码”表来混合编译和未编译的代码。

于 2012-08-21T14:36:08.390 回答
0

首先尝试使代码对您更易读的那个。如果它在您的目标机器上运行得足够快,请使用它。

如果它的运行速度不够快,请尝试另一个。

于 2012-07-30T16:43:21.887 回答
-1

lua 可以通过以下方式忽略多行:

function dostuff()
   blabla
   faaaaa

   --[[
   ignore this
   and this
   maybe this
   this as well
   ]]--
end
于 2014-03-30T11:34:31.007 回答