我正在向ws2812模塊添加一些代碼,以便能夠在某些類型的可重用緩衝區中存儲led值。NodeMCU/Lua性能問題
當前版本爲there。
我有兩個問題。
首先我想要一些「OO風格」的界面。所以我做:
local buffer = ws2812.newBuffer(300);
for j = 0,299 do
buffer:set(j, 255, 255, 255)
end
buffer:write(pin);
這裏的probleme是buffer:set
在每個循環轉,這是昂貴的解決(這個循環需要〜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
我找到了一個解決方法這個問題這看起來並不「好看」:
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.3ms的循環,超過4倍的速度),但它更像是一個黑客。 :/有沒有更好的方法來「緩存」緩衝區:設置分辨率?
第二個問題,在我的C代碼,我用:
ws2812_buffer * buffer = (ws2812_buffer*)luaL_checkudata(L, 1, "ws2812.buffer");
哪還給我的緩衝PTR,並檢查它是否是一個真正的ws2812.buffer
。但是這個電話很糟糕:在我的ESP8266上,〜50us。如果每次通話都完成(例如,我的300次buffer:set
),那就是〜15ms!
有沒有更好的方法來獲取一些用戶數據並檢查它的類型,還是應該在我的結構開始處添加一些「金絲雀」來做我自己的檢查(與50us相比,它幾乎是「免費的」)。 ..)?
請報告第二個版本比第一個版本快多少。 – lhf
添加後,4.3ms而不是20.2ms! – Alkorin
最好的方法是矢量化API函數,例如'setvec(jstart,jend,rstart,rend,bstart,gend,bstart,bend)',那麼你有**一個** C庫調用:'buffer:set(0,299,255,255,255, 255,255,255)',並且一個表查找的開銷在很大程度上是不相關的。 – TerryE