使用“数组类型”表格比使用“映射类型”表格能够提供更快的读取访问吗?

我正在使用Love2D在Lua中编写游戏。

每个实体显然都有x,y位置,这只是一个名为“position”的表,其中包含{x,y}(即{10,4})。

到目前为止,我一直在使用数组运算符来实现表格,因此要获取x值,我会调用position[1],要获取y值,我会调用position[2]。

然而,为了可读性,我更喜欢调用position.x和position.y。这将涉及使用表格的“映射”样式,例如position = {x=10, y=4}

虽然数组查找时间显然必须是O(1),但我担心使用映射样式会导致更糟糕的结果,因为映射在内部比简单数组复杂一百万倍。

在某种程度上,我怀疑性能差异并不重要,即使在我的主游戏循环中每分钟调用一百万次。我只是想更好地了解我用来创建这个游戏的工具。

谢谢!

点赞
用户183120
用户183120

摘自Roberto等人的《Lua 5.0实现》:

直到Lua 4.0,表格严格实现为哈希表:所有键值对都是显式存储的。Lua 5.0带来了一个新的算法,用于优化表格作为数组的使用:它通过不存储键而将值存储在实际数组中,通过优化具有整数键的对来优化数组。更准确地说,在Lua 5.0中,表格实现为混合数据结构:它们包含一个哈希部分和一个数组部分。

...

这种混合方案有两个优点。首先,使用整数键访问值更快,因为不需要哈希。其次,更重要的是,如果将表格用作数组,则数组部分占用的内存大约是哈希部分占用的一半,因为键在数组部分中是隐式的,但在哈希部分中是显式的。因此,如果表格被用作数组,并且其整数键是密集的,它表现为数组,而不支付哈希部分的任何内存或时间惩罚,因为哈希部分甚至不存在。

因此,是的,如果您使用Lua 5或更高版本,则仅将表格用作数组会在速度和内存方面有显着的差异。

“I doubt the performance difference would matter much, even if it's called a million times a minute in my main game loop.”

在对性能相关事项做出任何判断之前最好进行基准测试,因为通常是违反直觉的。如果性能可以承受打击并且您可以为可读性付出代价,那么您可能会满意 - 但以明智的方式做出这样的决定。

也许您无需牺牲可读性,如果可以编写辅助函数来获得相同的数据:

function X(t)
    return t[1]
end

function Y(t)
    return t[2]
end

local pos = { 8, 1 }
print(X(pos))
2016-01-22 08:56:42
用户936986
用户936986

是的,数组始终比表格快,但与执行其他任务所花费的时间相比,差异通常可以忽略不计。除非您将在具有数千个迭代的紧密循环中不断访问新的.x.y键,否则您甚至无需担心。

但是,如果您确实这样做,有几种方法可以缓解任何差异。

本地化检索的值:

- 旧 - 3次查找
result = obj.x + -[[some long calculations]] obj.x + -[[more long calculations]] obj.x

- 新 - 1次查找
local x = obj.x
result = x + -[[some long calculations]] x + -[[more long calculations]] x

继续使用数组,但为索引的魔术数定义“常数”以提高可读性

local X = 1
local Y = 2
print(“对象坐标为X:”..obj[X]..“,Y:”..obj[Y])
2016-01-22 11:11:25