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

发布于 2024-08-18 12:37:22 字数 30 浏览 5 评论 0原文

ps:更不用说闭包实现同一任务的代码复杂度了。

ps:let alone the code complexity of closure implementation of the same task.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猫性小仙女 2024-08-25 12:37:22

闭包的内存开销将小于协程的内存开销(除非闭包中有很多“上值”,而协程中没有)。此外,调用闭包的时间开销可以忽略不计,而调用协程的开销则很小。据我所知,Lua 在协程切换方面做得非常好,但如果性能很重要并且您可以选择不使用协程,那么您应该探索该选项。

如果您想自己进行基准测试,对于 Lua 中的此操作或其他任何操作:

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

您可以使用 os.clock() 来计时。

另请参阅 Lua 编程关于分析

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.

自由如风 2024-08-25 12:37:22

参见:
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")

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")

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文