[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Iterating pairs of keys from a table
- From: Chris Berardi <cberardi@...>
- Date: Tue, 28 Feb 2017 18:50:50 -0500
On Tue, Feb 28, 2017, at 06:18 PM, Tim Hill wrote:
>
> > 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
What about creating a tmp array?
local t = {};
for i=1,10000 do
t['k'..tostring(i)] = true
end
t1 = os.clock();
-- create tmp array
local tbl_,ix = {},1
for k,v in pairs(t) do tbl_[ix] = k; ix = ix + 1 end
local k1,k2,num
for i=1,#tbl_ do
for j=i+1,#tbl_ do
k1,k2 = t[i],t[j]
num = num + 1
end
end
t2 = os.clock();
print('elasped time for '..num..' => '..(t2-t1)..' sec')
Result average over 5 passes: 2.48 seconds