我正在向 ws2812 模块添加一些代码,以便能够拥有某种可重用的缓冲区,我们可以在其中存储 led 值。
当前版本在那里。
我有两个问题。
首先,我想要一些“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。如果每次通话都完成(buffer:set
例如我的 300 次),它是 ~15 毫秒!
有没有更好的方法来获取一些用户数据并检查其类型,或者我应该在结构的开头添加一些“金丝雀”来进行自己的检查(与 50us 相比,这几乎是“免费的”......)?