• Subject: Re: Why do we have ipairs?
• From: Andrew Starks <andrew.starks@...>
• Date: Tue, 10 Jun 2014 14:47:15 -0500

On Tuesday, June 10, 2014, Rena <hyperhacker@gmail.com> wrote:
On Tue, Jun 10, 2014 at 1:09 PM, Thiago L. wrote:

On 10/06/2014 13:14, Daurnimator wrote:
On 10 June 2014 12:03, Thiago L. wrote:
I thought # just used the array size? (you know, with OP_NEWTABLE you have hash size and array size... I thought # just returned that array size...)
Nope, it's a binary search for an item followed by a nil: http://www.lua.org/source/5.2/ltable.c.html#luaH_getn
In the worst case, it's a linear search.

This is because numeric indices are NOT always stored in the array portion of the table.

Also keep in mind that arrays need to grow and shrink, the sizes to NEWTABLE are only suggestions for initial memory allocation.

Also wouldn't this be faster and behave the same as ipairs: (in 5.1 at least... 5.2 can screw itself for all I care about... also I didn't test or benchmark it...)
local a,b,c = 1,#t,1
local v = t[a]
while a <= b and v ~= nil do
-- use this as if it is "for a,v in ipairs(t) do <...> end"
a = a + c
v = t[a]
end

No/not for all tables.
#t can be very slow (see the linear search worst case)

local a = 1

local v = t[a]
while v ~= nil do

-- use this as if it is "for a,v in ipairs(t) do <...> end"
a = a + 1
v = t[a]
end

I remember when 5.2(?) was in beta, there was some discussion about whether ipairs should be kept; the arguments against were that it's somewhat redundant, and the arguments for were that it's much more convenient than manually looping (and removing it would break old code with little benefit). Now that __ipairs has been added, you can also think of pairs() as "iterate all items in no particular order" and ipairs() as "iterate an array in order".

--
Sent from my Game Boy.

Not quite, of course.

Tables with hash pairs and a sequence yield are different. I love this feature of Lua.

-Andrew