lua中忽略代码最有效的方法是什么?

3
我有一段lua代码,我希望能够(有选择性地)忽略它。 我不能选择不读取它,并且有时我希望它被处理,有时不希望,所以我不能只注释掉它们(也就是说,有许多代码块,我要么选择阅读没有,要么阅读全部)。我想出了两种实现方式(可能有更多-我非常初学者):将代码包含在一个函数中,然后调用或不调用该函数(一旦确保已过调用该函数的点,我可以将其设置为 nil 来释放内存),或将代码包含在 if ... end 块中。前者稍微有些优点,因为有几个这样的块,并且使用前一种方法使得一个块更容易加载另一个块,即使主程序没有请求,但后者似乎更有效率。但是,由于我对此知之甚少,所以我不知道效率节省是否值得。那么,到底有多高效呢?
if false then
    -- a few hundred lines
end

than

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

如果这很大程度上取决于lua的实现,那么需要多少“几百行”才能可靠地发现区别,并且应该包括什么样的内容来进行最佳测试(块的主要用途是定义许多可能有用的函数)?


1
Lua的最新版本正在编译为字节码,因此,如果代码不被执行,无论您使用什么方法,数百行解析都不会产生大的运行时差异。 - Basile Starynkevitch
@BasileStarynkevitch 那么 if false then ... end 中没有效率检查吗?(我猜在读取时,条件状态实际上不经常出现,因此没有检查是有道理的。)顺便说一下,谢谢你的评论。 - Andrew Stacey
1
这里有一个更大的问题:你认为这很重要吗?你正在使用一种脚本语言;性能显然不是你所做的事情中最重要的。那么,你有理由相信其中一种模式比另一种模式明显地慢吗?只需使用最能描述你尝试编写的代码的方式;如果这是一个性能问题,那么在你知道它是一个性能问题之后再解决它就可以了。 - Nicol Bolas
2
@NicolBolas 我使用脚本语言,因为这是我唯一可以访问的东西(它在iPad上...)。虽然性能可能不是最重要的,但我不想故意削弱自己。此外,我现在所做的事情可能会被“定型”,以后切换到不同的方法将会非常麻烦,所以我宁愿第一次就把它做对。最后,作为一名数学家,务实并不容易。 - Andrew Stacey
4个回答

4
Lua并不聪明到可以转储函数的代码,因此您不会节省任何内存。就速度而言,您所说的是每个程序执行一次发生的纳秒差异。担心这个几乎与实际性能无关的问题会损害的效率。编写表达您意图最清晰的代码,而不要试图变得聪明过人。如果遇到性能问题,它将距离此决策有数百万英里之遥。如果您想节省内存(这在移动平台上是可以理解的),则可以将条件代码放在自己的模块中,并且仅在不需要时根本不加载它(如果您的框架支持;例如,MOAI支持,Corona不支持)。

甚至没有垃圾回收吗?啊,好吧。谢谢提供这些链接 - 观点非常有用。 - Andrew Stacey
测试很简单:collectgarbage('collect') 会强制进行垃圾回收循环,而 collectgarbage('count') 将向您显示 Lua 正在使用多少内存。 - Mud
我很惊喜地发现这些在特定实现中起作用。谢谢你给我所需的工具。 - Andrew Stacey

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函数透明地将其更改为按需从外部文件加载代码。此外,您可以通过使用“code”表填充“真实”函数来混合编译和未编译的代码。

0

在 Lua 中可以通过以下方式忽略多行:

function dostuff()
   blabla
   faaaaa

   --[[
   ignore this
   and this
   maybe this
   this as well
   ]]--
end

我在文档中找不到 --[[ ... ]]-- 语法;现在我可以停止使用 -- 注释掉多行代码的每一行了。 - Pietro

0

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

如果它运行得不够快,再尝试另一个。


其中一个因素是可扩展性:我将继续向中央存储库添加内容,因此尽管我现在可能无法检测到它,但在几个月后可能会发现。 - Andrew Stacey
那就重复执行相同的脚本100000次吧。 - kikito

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接