lua-users home
lua-l archive

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


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