I'm adding some code to the ws2812 module to be able to have some kind of reusable buffer where we could store led values.
The current version is there.
I've two problems.
First I wanted to have some "OO-style" interface. So I did:
local buffer = ws2812.newBuffer(300);
for j = 0,299 do
buffer:set(j, 255, 255, 255)
end
buffer:write(pin);
The probleme here is that buffer:set
is resolved at each loop turn, which is costly (this loop takes ~20.2ms):
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
I found a workaround for this problem which doesn't look "nice":
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);
It works well (4.3ms for the loop, more than 4 times faster), but it's more like a hack. :/ Is there a better way to "cache" the buffer:set resolution?
Second question, in my C code, I use:
ws2812_buffer * buffer = (ws2812_buffer*)luaL_checkudata(L, 1, "ws2812.buffer");
Which gives back my buffer ptr and check if it is really a ws2812.buffer
. But this call is sloooooow: on my ESP8266, ~50us. If it's done on each call (for my 300 time buffer:set
for example), it's ~15ms!
Is there a better way to fetch some user data and check its type, or should I add some "canary" at the beginning of my structure to do my own check (which will almost be "free" compared to 50us...)?