如何判断 Lua 闭包和 Lua 协程的权衡?(当它们都能执行相同的任务时)

让我们不谈闭包实现相同任务的代码复杂性。

原文链接 https://stackoverflow.com/questions/2092910

点赞
stackoverflow用户272427
stackoverflow用户272427

闭包的内存开销会比协程小(除非闭包中有大量 "upvalues",并且协程中没有)。此外,调用闭包的时间开销很小,而调用协程则有一些小的开销。从我所看到的情况来看,Lua 在协程切换方面做得很好,但如果性能很重要并且有不使用协程的选项,您应该探索一下该选项。

如果您想要在 Lua 中进行基准测试,可以使用以下方法:

使用 collectgarbage("collect");collectgarbage("count") 报告所有不可回收内存的大小。(您可能想要多次执行 "collect",而不仅仅是一次。)在创建某个东西(闭包、协程)之前和之后执行此操作,以了解它消耗了多少空间。

使用 os.clock() 计时。

另请参阅《Lua 编程》的性能分析一章。

2010-02-26 13:23:38
stackoverflow用户5657871
stackoverflow用户5657871

测试使用 NPL 运行时的 LuaJIT 2.1 协程开销

参见:https://gist.github.com/LiXizhi/911069b7e7f98db76d295dc7d1c5e34a

-- 测试 LuaJIT 2.1 中协程的开销

local total = 500000
local start, stop

function loopy(n)
  n = n + 1
  return n
end

print "开始函数测试 ..."
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("内存(KB):", collectgarbage("count") - beforeCount)
print("函数个数:", total)
print("经过时间:", stop-start, " s")

print "开始协程测试 ..."
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("内存(KB):", collectgarbage("count") - beforeCount)
print("协程个数:", total)
print("经过时间:", stop-start, " s")

print "开始单协程测试 ..."
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("内存(KB):", collectgarbage("count") - beforeCount)
print("协程个数:", total)
print("经过时间:", stop-start, " s")

--[[
总结:
1. 每个协程的内存开销为 0.26KB
2. yield/resume 对的开销为 0.0004 毫秒
如果你有 1000 个对象每秒调用 yield/resume,那么时间开销为 0.2 * 1000/500000 * 60 * 1000 = 24 毫秒
如果你不重用协程,那么内存开销为 1000 * 60 * 0.26 = 15.6MB/秒
]]
2022-05-16 01:25:59