LUA:具有大间隙的阵列的内存使用情况?

时间:2017-04-13 22:52:12

标签: arrays memory lua

如果我这样做:

listofstuff = {}
listofstuff[5] = 'foo'
listofstuff[9000] = 'bar'
listofstuff[200000] = 'baz'

它是否使用了比这更多的内存?

listofstuff = {}
listofstuff[0] = 'foo'
listofstuff[1] = 'bar'
listofstuff[2] = 'baz'

如果是,第一个示例是否创建了198998个空/未使用的表数组值,但仍占用内存来存储结构?

1 个答案:

答案 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开始。]