正如标题所说。如果我在 lua 中有一个表 p,则使用
table.remove(p)
与 if so 相同的
p[#p] = nil
表,这更快 - 我猜是第二个,但希望得到一些保证。
我所说的“相同”是指使用赋值为零时内部数组存储是否会缩小?我似乎在任何地方都找不到这个记录。将数组中的最后一个元素设置为 nil,或将数组中的最后 10 个元素设置为 nil 是否意味着数组将被缩小,或者它是否始终保留存储并且不再缩小数组?
我假设该数组是连续的,即它的每个数组条目中存储的值最多为#p。
As the title says. If I have a table p in lua, is using
table.remove(p)
the same as
p[#p] = nil
if so which is quicker - I'd guess the second, but would like some reassurance.
By the 'same as' I mean does the internal array storage shrink using assignment to nil? I can't seem to find this documented anywhere. Does setting the last element in an array to nil, or the last 10 elements in an array to nil mean the array will be shrunk, or does it always keep the storage and never shrink the array again?
I've assumed the array is contiguous, i.e. it has values stored in each array entry up to #p.
发布评论
评论(5)
将最后一个元素设置为 nil 将不是函数调用。那么这样一来,它肯定会比
table.remove
更快。这有多重要取决于你。没有记录;这允许改变实施。 Lua 承诺的只是将其设置为 nil 将减少后续调用 #p 返回的大小。除此之外的任何事情都取决于 Lua,并且肯定会在没有警告的情况下发生变化。这不是你应该依赖的东西。
然而,我谨建议,如果您正在考虑这些类型的微观优化,您可能不应该使用脚本语言。脚本语言应该用于性能不太重要而无需花费大量资金的代码。
Setting the last element to
nil
will not be a function call. So in that way, it will certainly be faster thantable.remove
. How much that matters is up to you.It isn't documented; this allows the implementation to change. All that Lua promises is that setting it to
nil
will decrease the size returned by subsequent calls to#p
. Anything more than that is up to Lua, and is certainly subject to change without warning. It's nothing you should rely on.However, I would respectfully suggest that if you're thinking about these kinds of micro-optimizations, you probably shouldn't be using a scripting language. A scripting language should be used for code where performance is not important enough to spend a great deal on.
p[#p] = nil
会更快,并且对于 table.remove 是最后一个位置的情况相同作为额外说明,
table.remove(func_call())
如果函数调用返回多个值,可能会出现意想不到的情况。p[#p] = nil
will be faster, and identical for the case where table.remove is the last positionAs an extra note,
table.remove(func_call())
may do unexpected things if the function call returns multiple values.从 Lua 5.1 VM 的实现开始,如 Roberto Ierusalimschy 的 Lua 性能技巧 中所述(Lua 的首席架构师),表的分配存储直到下一次表被重新哈希时才会改变 - 并且,正如一次又一次所说,你真的不应该考虑除非您有硬分析数据表明这是一个重大问题。
至于
table.remove(t)
和t[#t] = nil
之间的区别,请参阅我对 有什么区别`table.insert(t, i)` 和 `t[#t+1] = i`。Going from the implementation of the Lua 5.1 VM as described in Lua Performance Tips by Roberto Ierusalimschy (chief architect of Lua), the table's allocated storage doesn't change until the next time the table is rehashed - and, as stated time and time again, you really shouldn't be thinking about this unless you have hard profiling data showing it's a significant problem.
As for the difference between
table.remove(t)
andt[#t] = nil
, see my answer to What's the difference between `table.insert(t, i)` and `t[#t+1] = i`.我认为最好与添加和从数组类型表中删除元素保持一致。
table.insert
和table.remove
使您的代码保持一致且更易于阅读。回复:表格 Lua 不会调整表格的大小,直到您在先前删除的元素之后向其中添加第一个新元素为止。
I think it is better to be consistent with adding are removing elements from array type tables.
table.insert
andtable.remove
make your code consistent and easier to read.Re: tables Lua doesn't resize the table until you have added the first new element to it after having previously removed elements.
table.remove(p)
返回被删除的值。p[#p] = nil
不返回任何内容。table.remove(p)
returns the value that was removed.p[#p] = nil
does not return anything.