lua如何处理表格的增长?
它是否等同于Java中的ArrayList
?即需要连续的内存空间,当其大小超过已分配的空间时,内部数组将被复制到另一个内存空间。
有没有聪明的方法来处理这个问题?
我的问题是,表格如何存储在内存中?我不是在问如何在Lua中实现数组。
lua如何处理表格的增长?
它是否等同于Java中的ArrayList
?即需要连续的内存空间,当其大小超过已分配的空间时,内部数组将被复制到另一个内存空间。
有没有聪明的方法来处理这个问题?
我的问题是,表格如何存储在内存中?我不是在问如何在Lua中实现数组。
nil
作为空隙或作为空闲插槽)。 (会导致太多空插槽的数组候选项将放入哈希部分。如果数组部分已满但哈希部分有剩余空间,任何条目都将直接进入哈希部分。)对于数组和哈希部分,插入操作可能会触发调整大小,要么增加到下一个更大的2的幂次方,要么向下调整到任何更小的2的幂次方,如果之前已经删除了足够多的条目。(实际上触发向下调整大小是非常困难的:rehash
是调整表大小的唯一地方(两个部分同时调整大小),并且仅在luaH_newkey
中从if调用(如果两个部分都没有足够的空间)。)要了解更多信息,可以查看Lua 5.0实现的第4章,或检查源代码:基本上所有相关内容都发生在ltable.c
中,有趣的阅读起点是rehash
(在ltable.c
中)(调整大小函数),以及主解释器循环luaV_execute
(在lvm.c
中)或更具体地说luaV_settable
(也在那里)(在表中存储键值对时发生了什么)。
1举个例子,如果要缩小一个包含大型数组部分和没有哈希的表格,你需要清除所有数组条目,然后添加哈希部分的一个条目(即使用非整数键,该值可以是任何东西,包括nil
),以得到一个不包含数组部分和一个元素哈希部分的表格。
如果两个部分都包含条目,则必须首先清除哈希部分,然后添加足够的条目到数组部分以填充数组和哈希的组合(以触发调整大小,这将使您拥有一个大型数组部分和没有哈希的表格),然后像上面一样清除数组。2(先清除数组再清除哈希是行不通的,因为在清除两个部分之后,您将没有数组和一个巨大的哈希部分,并且您无法触发调整大小,因为任何条目都只会进入哈希。)
2实际上,更简单的方法是放弃原表格并新建一个表格。要确保表格被缩小,您需要知道实际分配的容量(它并不是当前条目数量,并且Lua不会直接告诉您),然后正确地获取所有步骤和所有大小 - 如果步骤的顺序错了或无法触发调整大小,则会得到一个巨大的表格,甚至可能在将其用作数组时性能更慢...(存储在哈希中的数组候选项也会存储它们的键,因此实际有用数据的数量是缓存行的一半。)
早期版本只有哈希表。优化用作数组的表的新算法:
与其他脚本语言不同, Lua不提供数组类型。相反,Lua程序员使用带整数索引的常规表来实现数组。Lua 5.0使用一种新的 算法,检测表是否被用作数组并自动将与数字索引相关联的值存储在实际数组中, 而不是将它们添加到哈希表中。这个算法在第4节中讨论。
nil
。如果一个表具有连续的正整数键且从1开始,则称该表具有“序列”。长度运算符#
仅适用于序列(或“空序列”),ipairs
在第一个缺失的正整数键之前结束。从而得到了实现的可能性。 - Tom Blodget