Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
NodeMCU/Lua性能问题_Lua_Esp8266_Nodemcu - Fatal编程技术网

NodeMCU/Lua性能问题

NodeMCU/Lua性能问题,lua,esp8266,nodemcu,Lua,Esp8266,Nodemcu,我正在向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.2ms): 我找到了一个

我正在向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.2ms):

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

它工作得很好(循环速度为4.3毫秒,快了4倍多),但更像是一种黑客行为。:/有没有更好的方法来“缓存”缓冲区:设置分辨率

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

ws2812_buffer * buffer = (ws2812_buffer*)luaL_checkudata(L, 1, "ws2812.buffer");
这将返回我的缓冲区ptr并检查它是否真的是
ws2812.buffer
。但这个电话是斯洛:在我的ESP8266上,~50us。如果每次调用都完成了(例如,对于我的300次
buffer:set
),则为~15ms


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

让它看起来不像你可以尝试使用的黑客行为

local set = buffer.set
这基本上是相同的代码,但是没有getmetatable,因为metatable是通过
\uu index
元方法隐式使用的

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


我想说测试元表比包装慢,因为
luaL_checkudata
做了大量工作来获取和测试元表,通过包装我们可以直接访问类型。不过,基准测试会告诉你答案。

请报告第二个版本比第一个版本快多少。在文章中添加了4.3ms,而不是20.2ms!最好的方法是对API函数进行矢量化,例如
setvec(jstart,jend,rstart,rend,bstart,gend,bstart,bend)
,然后你就有了一个C库调用:
buffer:set(0,299,255,255,255,255,255)
,而一个表查找的开销基本上是无关的,我无法预测下一种颜色:它主要来自查找表和/或一些数学函数。这就是我搜索优化简单调用的原因;)但在某些情况下,我计划处理表的表,以便能够重用一些存储的模式:
set(start,{{g,r,b},{g,r,b},…})
确实有效。。。不知道为什么我一直使用冒号语法:/谢谢@Alkorin I做了一些非常糟糕的测试,它清楚地显示了在使用包装器而不是元表检查时的加速。以下是我弄乱的代码:
ws2812_buffer * buffer = (ws2812_buffer*)luaL_checkudata(L, 1, "ws2812.buffer");
local set = buffer.set