In [5]:
local q = {}
local chronos = require("chronos")
local bench = function(name, func, loops)
                  loops=loops or 1000

                  local q0 = chronos.nanotime()
                  for i=1,loops do
                      func()
                  end
                  local q1 = chronos.nanotime()
                  local time = q1 - q0
                  print (name .. " took " .. time/loops)
              end
local createList = function(size)
    res = {}
    for i=1,size do
        res[i] = math.random()
    end
    return res
end

q['wrap'] = function (arg)
              return coroutine.create(
                     function()
                         local n = 1
                         while 1 do
                             if n > #arg
                             then
                                 return
                             end
                             coroutine.yield(arg[n])
                             n = n + 1
                         end
                     end)
           end

q['add'] = function (arg1, arg2)
              return coroutine.create(
                     function()
                         while 1 do
                             local status1, value1 = coroutine.resume(arg1)
                             local status2, value2 = coroutine.resume(arg2)
                             if not status1 == status2
                             then
                                 error("mismatched")
                             end
                             if not status1
                             then
                                 return
                             end
                             coroutine.yield(value1 + value2)
                         end
                     end)
          end


q['addBasic'] = function(arg1, arg2)
                    if #arg1 ~= #arg2 then
                        print ("Error: Unequal lengths" .. #arg1 .. " is not same as " .. #arg2)
                        return
                    end
                    res = {}
                    for i = 1, #arg1 do
                        res[i] = arg1[i] + arg2[i]
                    end
                    return res
                end

q['sub'] = function (arg1, arg2)
              return coroutine.create(
                     function()
                         while 1 do
                             local status1, value1 = coroutine.resume(arg1)
                             local status2, value2 = coroutine.resume(arg2)
                             if not status1 == status2
                             then
                                 error("mismatched")
                             end
                             if not status1
                             then
                                 return
                             end
                             coroutine.yield(value1 - value2)
                         end
                     end)
          end

q['mul'] = function (arg1, arg2)
              return coroutine.create(
                     function()
                         while 1 do
                             local status1, value1 = coroutine.resume(arg1)
                             local status2, value2 = coroutine.resume(arg2)
                             if not status1 == status2
                             then
                                 error("mismatched")
                             end
                             if not status1
                             then
                                 return
                             end
                             coroutine.yield(value1 * value2)
                         end
                     end)
          end

local as = createList(2)
local bs = createList(2)
local simpleFunction = function()
    return q.addBasic(as, bs)
end

local coroutineFunction = function()
    routine = q.add(q.wrap(as), q.wrap(bs))
    for i= 1,#as do
        local status, result = coroutine.resume(routine)
    end
end


local al = createList(10)
local bl = createList(10)

local simpleFunctionLong = function()
    return q.addBasic(al, bl)
end

local coroutineFunctionLong = function()
    routine = q.add(q.wrap(al), q.wrap(bl))
    for i= 1,#al do
        local status, result = coroutine.resume(routine)
    end
end

local ax = createList(1000*100)
local bx = createList(1000*100)

local simpleFunctionXLong = function()
    return q.addBasic(ax, bx)
end

local coroutineFunctionXLong = function()
    routine = q.add(q.wrap(ax), q.wrap(bx))
    for i= 1,#ax do
        local status, result = coroutine.resume(routine)
    end
    return
end

local simpleSingleCompoundFunctionXLong = function()
    local t1 = q.addBasic(ax, bx)
    return q.addBasic(ax, t1)
end

local coroutineSingleCompoundFunctionXLong = function()
    routine = q.add(q.wrap(ax) , q.add(q.wrap(ax), q.wrap(bx)))
    for i= 1,#ax do
        local status, result = coroutine.resume(routine)
    end
    return
end

local simpleDoubleCompoundFunctionXLong = function()
    local t1 = q.addBasic(ax, bx)
    local t2 = q.addBasic(t1, bx)
    return q.addBasic(ax, t2)
end

local coroutineDoubleCompoundFunctionXLong = function()
    routine = q.add(q.wrap(ax) , q.add(q.wrap(bx) , q.add(q.wrap(ax), q.wrap(bx))))
    for i= 1,#ax do
        local status, result = coroutine.resume(routine)
    end
    return
end

local simpleTripleCompoundFunctionXLong = function()
    local t1 = q.addBasic(ax, bx)
    local t2 = q.addBasic(t1, bx)
    local t3 = q.addBasic(t2, ax)
    return q.addBasic(ax, t3)
end

local coroutineTripleCompoundFunctionXLong = function()
    routine = q.add(q.wrap(ax) ,q.add(q.wrap(ax) , q.add(q.wrap(bx) , q.add(q.wrap(ax), q.wrap(bx)))))
    for i= 1,#ax do
        local status, result = coroutine.resume(routine)
    end
    return
end

foo = q.sub(q.mul(q.wrap({1,2}), q.add(q.wrap({3,4}), q.wrap({5,6}))), q.wrap({7,8}))
bench("co routine", coroutineFunction, 1000*100)
bench("simple", simpleFunction, 1000*100)
bench("co routine long", coroutineFunctionLong, 1000*100)
bench("simple long ", simpleFunctionLong, 1000*100)
bench("co routine Xlong", coroutineFunctionXLong, 100)
bench("simple Xlong ", simpleFunctionXLong, 100)
bench("co routine compound single Xlong", coroutineSingleCompoundFunctionXLong, 100)
bench("simple compound single Xlong ", simpleSingleCompoundFunctionXLong, 100)
bench("co routine compound double Xlong", coroutineDoubleCompoundFunctionXLong, 100)
bench("simple compound double Xlong ", simpleDoubleCompoundFunctionXLong, 100)
bench("co routine triple Xlong", coroutineTripleCompoundFunctionXLong, 100)
bench("simple triple Xlong ", simpleTripleCompoundFunctionXLong, 100)


co routine took 5.9398674999829e-06
simple took 7.7851996997197e-07
co routine long took 1.2502850300007e-05
simple long  took 2.4064859999635e-06
co routine Xlong took 0.098295727400036
simple Xlong  took 0.0076583272599964
co routine compound single Xlong took 0.15846040465003
simple compound single Xlong  took 0.015615433589992
co routine compound double Xlong took 0.21677163562999
simple compound double Xlong  took 0.02359367623998
co routine triple Xlong took 0.27320877539001
simple triple Xlong  took 0.030400494109999

In [9]:
local q = {}
local chronos = require("chronos")
local bench = function(name, func, loops)
                  loops=loops or 1000

                  local q0 = chronos.nanotime()
                  for i=1,loops do
                      func()
                  end
                  local q1 = chronos.nanotime()
                  local time = q1 - q0
                  print (name .. " took " .. time/loops)
              end
local createList = function(size)
    res = {}
    for i=1,size do
        res[i] = math.random()
    end
    return res
end

q['wrap'] = function (arg)
    local chunkSize = 64
              return coroutine.create(
                     function()
                         local n = 1
                         local res = {}
                         while 1 do
                             if n > #arg
                             then
                                 return res
                             else 
                                 if #res == chunkSize then
                                    coroutine.yield(res)
                                    res = {}
                                else
                                    res[#res + 1] = arg[n]
                                end
                             end
                             coroutine.yield(arg[n])
                             n = n + 1
                         end
                     end)
           end

q['add'] = function (arg1, arg2)
              return coroutine.create(
                     function()
                         while 1 do
                             local status1, value1 = coroutine.resume(arg1)
                             local status2, value2 = coroutine.resume(arg2)
                             if not status1 == status2
                             then
                                 error("mismatched")
                             end
                             if not status1
                             then
                                 return
                             end
                             coroutine.yield(q.addBasic(value1, value2))
                         end
                     end)
          end


q['addBasic'] = function(arg1, arg2)
                    if #arg1 ~= #arg2 then
                        print ("Error: Unequal lengths" .. #arg1 .. " is not same as " .. #arg2)
                        return
                    end
                    res = {}
                    for i = 1, #arg1 do
                        res[i] = arg1[i] + arg2[i]
                    end
                    return res
                end

q['sub'] = function (arg1, arg2)
              return coroutine.create(
                     function()
                         while 1 do
                             local status1, value1 = coroutine.resume(arg1)
                             local status2, value2 = coroutine.resume(arg2)
                             if not status1 == status2
                             then
                                 error("mismatched")
                             end
                             if not status1
                             then
                                 return
                             end
                             coroutine.yield(value1 - value2)
                         end
                     end)
          end

q['mul'] = function (arg1, arg2)
              return coroutine.create(
                     function()
                         while 1 do
                             local status1, value1 = coroutine.resume(arg1)
                             local status2, value2 = coroutine.resume(arg2)
                             if not status1 == status2
                             then
                                 error("mismatched")
                             end
                             if not status1
                             then
                                 return
                             end
                             coroutine.yield(value1 * value2)
                         end
                     end)
          end

local as = createList(2)
local bs = createList(2)
local simpleFunction = function()
    return q.addBasic(as, bs)
end

local coroutineFunction = function()
    routine = q.add(q.wrap(as), q.wrap(bs))
    for i= 1,#as do
        local status, result = coroutine.resume(routine)
    end
end


local al = createList(10)
local bl = createList(10)

local simpleFunctionLong = function()
    return q.addBasic(al, bl)
end

local coroutineFunctionLong = function()
    routine = q.add(q.wrap(al), q.wrap(bl))
    for i= 1,#al do
        local status, result = coroutine.resume(routine)
    end
end

local ax = createList(1000*100)
local bx = createList(1000*100)

local simpleFunctionXLong = function()
    return q.addBasic(ax, bx)
end

local coroutineFunctionXLong = function()
    routine = q.add(q.wrap(ax), q.wrap(bx))
    for i= 1,#ax do
        local status, result = coroutine.resume(routine)
    end
    return
end

local simpleSingleCompoundFunctionXLong = function()
    local t1 = q.addBasic(ax, bx)
    return q.addBasic(ax, t1)
end

local coroutineSingleCompoundFunctionXLong = function()
    routine = q.add(q.wrap(ax) , q.add(q.wrap(ax), q.wrap(bx)))
    for i= 1,#ax do
        local status, result = coroutine.resume(routine)
    end
    return
end

local simpleDoubleCompoundFunctionXLong = function()
    local t1 = q.addBasic(ax, bx)
    local t2 = q.addBasic(t1, bx)
    return q.addBasic(ax, t2)
end

local coroutineDoubleCompoundFunctionXLong = function()
    routine = q.add(q.wrap(ax) , q.add(q.wrap(bx) , q.add(q.wrap(ax), q.wrap(bx))))
    for i= 1,#ax do
        local status, result = coroutine.resume(routine)
    end
    return
end

local simpleTripleCompoundFunctionXLong = function()
    local t1 = q.addBasic(ax, bx)
    local t2 = q.addBasic(t1, bx)
    local t3 = q.addBasic(t2, ax)
    return q.addBasic(ax, t3)
end

local coroutineTripleCompoundFunctionXLong = function()
    routine = q.add(q.wrap(ax) ,q.add(q.wrap(ax) , q.add(q.wrap(bx) , q.add(q.wrap(ax), q.wrap(bx)))))
    for i= 1,#ax do
        local status, result = coroutine.resume(routine)
    end
    return
end

--foo = q.sub(q.mul(q.wrap({1,2}), q.add(q.wrap({3,4}), q.wrap({5,6}))), q.wrap({7,8}))
--bench("co routine", coroutineFunction, 1000*100)
--bench("simple", simpleFunction, 1000*100)
--bench("co routine long", coroutineFunctionLong, 1000*100)
--bench("simple long ", simpleFunctionLong, 1000*100)
--bench("co routine Xlong", coroutineFunctionXLong, 100)
--bench("simple Xlong ", simpleFunctionXLong, 100)

bench("co routine single ", coroutineSingleCompoundFunctionXLong, 1000)
bench("simple single ", simpleSingleCompoundFunctionXLong, 1000)
bench("co routine double ", coroutineDoubleCompoundFunctionXLong, 1000)
bench("simple double ", simpleDoubleCompoundFunctionXLong, 1000)
bench("co routine triple ", coroutineTripleCompoundFunctionXLong, 1000)
bench("simple triple ", simpleTripleCompoundFunctionXLong, 1000)


co routine single  took 0.021671157268
simple single  took 0.015056456852995
co routine double  took 0.021691592121999
simple double  took 0.023220143451996
co routine triple  took 0.022054084075004
simple triple  took 0.031607336400004

In [ ]: