LUA: 数组中有大间隔的情况下的内存使用?

如果我这样做:

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

它使用的内存比这个多吗?

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

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

点赞
用户805875
用户805875

是的,它会使用更多的内存(大约是原来的2倍),但不会存储成千上万/百万个空槽。

在内部,表格是哈希图。它们只会分配足够存储您存放的值所需的槽位(向上舍入到下一个二的幂)。这意味着

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

将创建一个表格存储大约包含四个槽位的内容(粗略的伪表示法)

{
  -- 忽略不相关的元数据
  -- (查看 Lua 代码(ltable.c/ltable.h)以获取完整细节)
  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开始。]

2017-04-13 23:57:32