如果我这样做:
listofstuff = {}
listofstuff[5] = 'foo'
listofstuff[9000] = 'bar'
listofstuff[200000] = 'baz'
它是否使用了比这更多的内存?
listofstuff = {}
listofstuff[0] = 'foo'
listofstuff[1] = 'bar'
listofstuff[2] = 'baz'
如果是,第一个示例是否创建了198998个空/未使用的表数组值,但仍占用内存来存储结构?
答案 0 :(得分:2)
是的,它将使用更多内存(大约2倍),但不会,它不会存储数千/数百万个空插槽。
在内部,表是哈希映射。它们只根据需要分配尽可能多的插槽来存储您放入的值(向上舍入到下一个2的幂)。这意味着
listofstuff = {}
listofstuff[5] = 'foo'
listofstuff[9000] = 'bar'
listofstuff[200000] = 'baz'
将创建一个包含四个槽的表(粗伪表示法)
{
-- irrelevant metadata omitted
-- (look at the Lua code (ltable.c/ltable.h) for the full details
arraysize = 0,
hashsize = 4,
array = null,
hash = {
{ num:5, str:"foo" },
{ dummy, dummy },
{ num:200000, str:"bar" },
{ num:9000, str:"bar"},
},
}
(这只是一个例子,订单可能完全不同。)
你的另一个例子将存储大致类似的东西:
{
arraysize = 2,
hashsize = 1,
array = { str:"bar", str:"baz" },
hash = {
{ num:0, str:"foo" },
},
}
如果您有一个连续范围的整数键,如果值存储为数组,则无需存储键(节省一半内存)。 (然后该数组中的位置是键。)
[与Lua中的所有地方一样,数组从1开始。但是如果你的数组从0开始就没有问题 - 额外的插槽只是与密钥一起存储在散列中。如果你没有充分的理由从0开始,那么从1开始。但如果你必须调整算法或公式来做到这一点,那就从0开始。]