使用"数组样式"表格提供比使用"地图样式更快的读取访问权限"表?

时间:2016-01-22 07:40:07

标签: lua

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

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

到目前为止,我一直在使用数组运算符实现表,所以为了得到x值,我调用位置[1],得到y值我调用位置[2]。

然而,为了便于阅读,我更倾向于调用position.x和position.y。这将涉及在他们的" map"中使用表格。风格,如position = {x=10, y=4}

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

在某种程度上,我怀疑性能差异会有多大影响,即使它在我的主游戏循环中每分钟被称为百万次。我只是想更好地理解我用来创建这个游戏的工具。

谢谢!

2 个答案:

答案 0 :(得分:4)

摘自Roberto等人的Implementation of Lua 5.0

  

在Lua 4.0之前,表格严格地作为哈希表实现:所有对都是   明确存储。 Lua 5.0带来了一种新算法来优化表的使用   作为数组:它通过不存储键并将值存储在实际数组中来优化具有整数键的对。更确切地说,在Lua 5.0中,表被实现为混合数据结构:它们包含散列部分和数组部分。

     

[...]

     

这种混合方案有两个优点。首先,使用整数键访问值更快,因为不需要散列。其次,更重要的是,数组部分占用的内存大约是存储在散列部分中所占用的内存的一半,因为密钥隐含在数组部分中但在散列部分中是显式的。因此,如果将表用作数组,则只要其整数键密集,它就会作为数组执行。此外,哈希部分没有内存或时间损失,因为它甚至不存在。

所以,是的,如果你使用Lua 5或更高版本,那么只使用表作为数组,速度和内存应该存在显着差异。

  

我怀疑性能差异是否很重要,即使它在我的主游戏循环中被称为每分钟一百万次。

在结束与性能相关的任何事情之前,最好先进行基准测试,因为这通常是违反直觉的。对于可读性而言,你可能会对表现感到满意 - 但是要以明智的方式这样做。

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

function X(t)
    return t[1]
end

function Y(t)
    return t[2]
end

local pos = { 8, 1 }
print(X(pos))

答案 1 :(得分:3)

是的,数组总是比表快,但与执行其他任务所花费的时间相比,差异通常可以忽略不计。除非您经常在非常紧密的循环中访问新的.x.y密钥,否则您甚至不应该打扰。

但是,如果您这样做,可以使用几种方法来减轻差异。

本地化您检索到的值:

-- Old - 3 lookups
result = obj.x + --[[ some long calculations ]] obj.x + --[[ more long calculations ]] obj.x

-- New - 1 lookup
local x = obj.x
result = x + --[[ some long calculations ]] x + --[[ more long calculations ]] x

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

local X = 1
local Y = 2
print("Object coordinates are X: " .. obj[X] .. ", Y: " .. obj[Y])