lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> On Feb 28, 2017, at 12:24 AM, Dirk Laurie <dirk.laurie@gmail.com> wrote:
> 
> 2017-02-28 5:38 GMT+02:00 Tim Hill <drtimhill@gmail.com>:
>> Anyway, I came up with this generator function:
>> 
>> function keypairs(t)
>>    local s = next(t)
>>    local n, i = next(t, s), s
>>    return function()
>>        i = next(t, i)
>>        if i == nil then
>>            s, n = n, next(t, n)
>>            i = n
>>            if i == nil then s = nil end
>>        end
>>        return s, i
>>    end
>> end
>> 
> 
> One could use a coroutine. That saves a lot of bookkeeping.
> 
> keypairs = function(tbl)
>  return coroutine.wrap(
>    function()
>      for k in next,tbl do
>        for m in next,tbl,k do
>          coroutine.yield(k,m)
>        end
>      end
>    end)
>  end
> 

Very nice idea, and very clean, though I worry about the performance. Out of curiosity I ran a simple timing test with both approaches:

t = {}
for i = 1, 10000 do
	t["k" .. tostring(i)] = true
end

t1 = os.clock()
for k1, k2 in keypairs(t) do
	;
end
t2 = os.clock()
print("elapsed time=", t2 - t1)

Results averaged over 5 passes:
Non-coroutine: 7.65 seconds
Coroutine: 14.34 seconds

Of course, this does nothing WITH the pairs, and in a real world situation its quite possible that any processing overhead would render the difference in iterator performance moot.

—Tim