开发者

how to judge of the trade-off of lua closure and lua coroutine?(when both of them can perform the same task)

ps:let alone the 开发者_运维知识库code complexity of closure implementation of the same task.


The memory overhead for a closure will be less than for a coroutine (unless you've got a lot of "upvalues" in the closure, and none in the coroutine). Also the time overhead for invoking the closure is negligible, whereas there is some small overhead for invoking the coroutine. From what I've seen, Lua does a pretty good job with coroutine switches, but if performance matters and you have the option not to use a coroutine, you should explore that option.

If you want to do benchmarks yourself, for this or anything else in Lua:

You use collectgarbage("collect");collectgarbage("count") to report the size of all non-garbage-collectable memory. (You may want to do "collect" a few times, not just one.) Do that before and after creating something (a closure, a coroutine) to know how much size it consumes.

You use os.clock() to time things.

See also Programming in Lua on profiling.


see also: https://gist.github.com/LiXizhi/911069b7e7f98db76d295dc7d1c5e34a

-- Testing coroutine overhead in LuaJIT 2.1 with NPL runtime
--[[ 
Starting function test...
memory(KB): 0.35546875
Functions:  500000
Elapsed time:   0    s
Starting coroutine test...
memory(KB): 13781.81640625
Coroutines: 500000
Elapsed time:   0.191    s
Starting single coroutine test...
memory(KB): 0.4453125
Coroutines: 500000
Elapsed time:   0.02800000000002
conclusions:
1. memory overhead: 0.26KB per coroutine
2. yield/resume pair overhead: 0.0004 ms
if you have 1000 objects each is calling yield/resume at 60FPS, then the time overhead is 0.2*1000/500000*60*1000 = 24ms
and if you do not reuse coroutine, then memory overhead is 1000*60*0.26 = 15.6MB/sec
]]

local total = 500000
local start, stop
function loopy(n)
  n = n + 1 
  return n
end

print "Starting function test..."
collectgarbage("collect");collectgarbage("collect");collectgarbage("collect");
local beforeCount =collectgarbage("count")
start = os.clock()
for i = 1, total do
  loopy(i)
end
stop = os.clock()
print("memory(KB):", collectgarbage("count") - beforeCount)
print("Functions:", total)
print("Elapsed time:", stop-start, " s")

print "Starting coroutine test..."
collectgarbage("collect");collectgarbage("collect");collectgarbage("collect");
local beforeCount =collectgarbage("count")
start = os.clock()
for i = 1, total do
  co = coroutine.create(loopy)
  coroutine.resume(co, i)
end
stop = os.clock()
print("memory(KB):", collectgarbage("count") - beforeCount)
print("Coroutines:", total)
print("Elapsed time:", stop-start, " s")


print "Starting single coroutine test..."
collectgarbage("collect");collectgarbage("collect");collectgarbage("collect");
local beforeCount =collectgarbage("count")
start = os.clock()
co = coroutine.create(function()
    for i = 1, total do
      loopy(i)
      coroutine.yield();
    end
end)

for i = 1, total do
  coroutine.resume(co, i)
end

stop = os.clock()
print("memory(KB):", collectgarbage("count") - beforeCount)
print("Coroutines:", total)
print("Elapsed time:", stop-start, " s")

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜