我是否基本上是通过使我的本地功能全球化来做额外的工作吗?



我读到将大多数函数保留在本地而不是全局更快更好。
所以我正在这样做:

input = require("input")
draw = require("draw")

然后在输入中.lua例如:

local tableOfFunctions = {isLetter = isLetter, numpadCheck = numpadCheck, isDigit = isDigit, toUpper = toUpper}
return tableOfFunctions

其中 isLetter、numpadCheck 等是该文件的本地函数。 然后我像这样调用函数:

input.isLetter(key)

现在,我的问题是:我是在用这个重新发明轮子吗?全局函数不是存储在 lua 表中吗?我喜欢输入的外观。在函数名称之前,保持它漂亮整洁,所以如果它不是一个糟糕的编码实践,我可以保留它。

根据您的个人需求重新发明轮子是Lua的核心。 你描述的方法被lua创作者自己在他的书中描述为有效的方法,在这里。

Lua 中的所有内容都存储在表中。"更快"的局部函数(以及更快的局部变量)来自如何查找全局值和上值的方式。 在这一行的下方,引用了游戏论坛上碰巧出现的关于速度的更详细解释的相关部分。 除此之外,由于代码的清洁性和防错性,建议当地人使用。


在 lua 中,使用 {} 创建表,此运算符在 ram 中为表保留一定量的内存。保留的空间保持不变且不可移动,例外是脚本编写者不应关心的实现细节。 将表分配给的任何变量

a={}; 
b={ c={a} }

只是指向内存中表的指针。指针占用 32 或 64 位,仅此而已。 每当您传递表时,只会复制这 64 位。 每当查询表中的表时:

return b.c[1]

计算机跟随存储在b中的指针,在RAM中找到一个表对象,查询它以获取键"C",获取指向另一个表的指针,查询键"1"然后返回指向表a的指针。只是一个简单的指针跳跃,工作量与算术相当。

每个函数都有关联的表_ENV,任何变量查找

return a

实际上是对该表的查询

return _ENV.a

如果变量是局部变量,则存储在_ENV中。

如果_ENV中没有具有给定名称的变量,则查询全局变量,这些变量实际上驻留在顶级表中,即脚本根函数的_ENV(它是加载和执行脚本的requiredofile函数)。 通常,指向全局表的链接以_G的形式存储在任何其他_ENV中。所以访问全局变量

return b

其实是这样的

return _ENV.b or _ENV._G.b

因此,它大约是 3 次指针跳跃而不是 1 次。 这是一个复杂的示例,应该可以让您深入了解这意味着的工作量:

%RUN THIS IN STANDALONE LUA INTERPRETER
local depth=100--how many pointers will be in a chain
local  q={};--a table
local a={};--a start of pointer chain
local b=a;  -- intermediate variable
for i=1,depth do b.a={} b=b.a end;  --setup chain
local t=os.clock(); 
print(q)  
print(os.clock()-t);--time of previous line execution 
t=os.clock(); --start of pointer chain traversal
b=a 
while b.a do b=b.a end 
print(b) 
print(os.clock()-t)--time of pointer traversal

当指针链大约有 100 个元素时,系统负载波动实际上可能会导致第二次更小。只有当您将depth更改为数千个或更多的中间指针时,直接访问才会明显更快。

请注意,每当您查询未初始化的变量时,都会进行所有 3 次跳转。

全局变量存储在保留表_G中(您可以随时检查其内容),但避免使用全局变量是一种良好的编程习惯。

除非有很好的理由不这样做,否则您的餐桌input也应该local

来自Lua编程:

尽可能使用局部变量是一种很好的编程风格。局部变量可帮助您避免使用不必要的名称使全局环境混乱。此外,对局部变量的访问比对全局变量的访问更快。

最新更新