socket2810 wrote:Perhaps my solution returning the table contents orderly takes its toll on Lua.
You're not returning them orderly as there is no order to them in the first place. Using pairs/next is inherently unpredictable (except perhaps for next on numeric keys) as far as key order is concerned.
In your function you're using
table.insert/remove which is one of the slowest methods of adding/removing a value to an array. You're also creating many tables to store your iterator and state.
The other factor in regards to speed is localization of variables, doing
table.x is in fact indexing a table called
table for key
x. Localizing functions that you use repeatedly - before using them - will in simple traversals such as these increase relative speed by quite a bit. The only non localized variables used in my "next" variant is the function
next and
type.
Try measuring the speed of the various functions once you localize things like
coroutine.yield
Example:
Code: Select all
local coroutine_yield = coroutine.yield
local coroutine_wrap = coroutine.wrap
local type = type
local pairs = pairs
local function process(value,key,passed)
local passed = passed or {} --in case of loops
if (type(value)=="table" and passed[value]==nil) then
passed[value] = true
for k,v in pairs(value) do
process(v,k,passed)
end
else
coroutine_yield(key,value)
end
end
local function iter_function(e)
return coroutine_wrap(process),e
end
socket2810 wrote:I still can't understand how you're using next in your "stack"
next(table,key) called without key argument returns the "first" key and value of a table, called on my stack it in essence returns any key-value pair inside the stack, which is respectively a table in queue to be processed and the last key from the table that was processed.
I'm using the
_new variable to represent
nil inside the stack so that I can add tables on which next wasn't called yet, since adding
nil to a key doesn't create a new table field.