【问题标题】:NodeMCU/Lua performance issuesNodeMCU/Lua 性能问题
【发布时间】:2016-04-01 00:42:58
【问题描述】:

我正在向 ws2812 模块添加一些代码,以便能够拥有某种可重用的缓冲区,我们可以在其中存储 LED 值。

当前版本是there

我有两个问题。

首先我想要一些“OO 风格”的界面。所以我做了:

local buffer = ws2812.newBuffer(300);
for j = 0,299 do
   buffer:set(j, 255, 255, 255)
end
buffer:write(pin);

这里的问题是buffer:set 在每个循环转弯处被解析,这是昂贵的(这个循环需要大约 20.2 毫秒):

8       [2]     FORPREP         1 6     ; to 15
9       [3]     SELF            5 0 -7  ; "set"
10      [3]     MOVE            7 4
11      [3]     LOADK           8 -8    ; 255
12      [3]     LOADK           9 -8    ; 255
13      [3]     LOADK           10 -8   ; 255
14      [3]     CALL            5 6 1
15      [2]     FORLOOP         1 -7    ; to 9

我为这个问题找到了一个看起来不太“好”的解决方法:

local buffer = ws2812.newBuffer(300);
local set = getmetatable(buffer).set;
for j = 0,299 do
   set(buffer, j, 255, 255, 255)
end
buffer:write(pin);

它运行良好(循环 4.3 毫秒,快 4 倍以上),但它更像是一个 hack。 :/ 有没有更好的方法来“缓存”缓冲区:设置分辨率?

第二个问题,在我的 C 代码中,我使用:

ws2812_buffer * buffer = (ws2812_buffer*)luaL_checkudata(L, 1, "ws2812.buffer");

它会返回我的缓冲区 ptr 并检查它是否真的是 ws2812.buffer。但是这个电话很慢:在我的 ESP8266 上,~50us。如果每次通话都完成(例如,我的 300 次 buffer:set),大约需要 15 毫秒!

有没有更好的方法来获取一些用户数据并检查其类型,或者我应该在结构的开头添加一些“金丝雀”来进行自己的检查(与 50us 相比,这几乎是“免费的”...... .)?

【问题讨论】:

  • 请报告第二个版本比第一个版本快多少。
  • 在帖子中添加,4.3 毫秒而不是 20.2 毫秒!
  • 最好的方法是矢量化 API 函数,例如setvec(jstart, jend, rstart, rend, bstart, gend, bstart, bend),那么你有 一个 C 库调用:buffer:set(0, 299, 255, 255, 255, 255, 255, 255) 并且单表查找的开销在很大程度上是无关紧要的。
  • 是也不是@TerryE,我无法预测下一个颜色:它主要来自查找表和/或一些数学函数。这就是我搜索优化简单调用的原因;)但在某些情况下,我计划处理表以便能够重用一些存储的模式:set(start, {{g, r, b},{g, r, b},...})

标签: lua esp8266 nodemcu


【解决方案1】:

为了让它看起来不那么黑客,你可以尝试使用

local set = buffer.set

这基本上是相同的代码,但没有 getmetatable,因为 metatable 通过 __index 元方法隐式使用。

在我们的项目中,我们自己实现了luaL_checkudata。 一个选项 - 正如您同样建议的那样 - 是使用包含该类型的包装器对象。由于假设所有用户数据都被包装在包装器中,我们可以使用它来获取和确认用户数据的类型。但是没有进行基准测试,而是使用了测试元表。

我会说测试元表比包装慢,因为luaL_checkudata 做了很多工作来获取和测试元表,并且通过包装我们可以直接访问类型。然而,基准测试肯定会证明这一点。

【讨论】:

  • 确实有效...不知道为什么我坚持使用冒号语法:/谢谢!
  • @Alkorin 我做了一些非常很差的测试,它清楚地显示了使用包装器而不是元表检查时的加速。这是我弄乱的代码:gist.github.com/Rochet2/c61cc0ecb05ecbea2291
猜你喜欢
  • 2019-05-18
  • 2015-11-17
  • 2015-05-30
  • 2016-01-19
  • 2023-03-18
  • 2015-02-21
  • 2016-08-15
  • 2019-05-21
  • 2019-05-06
相关资源
最近更新 更多