String 高效地在字符串中搜索一组字符并返回第一个匹配项
我正在将vt100(旧学校终端)实现到lua中,它在嵌入式MCU上运行。性能是这里的一个问题 给定的是一个字符串(输入行),其中包含多个(不可预测的数字)字符。 在这个字符串中,我想从一组字符中找到第一个匹配项 例如:String 高效地在字符串中搜索一组字符并返回第一个匹配项,string,performance,lua,match,String,Performance,Lua,Match,我正在将vt100(旧学校终端)实现到lua中,它在嵌入式MCU上运行。性能是这里的一个问题 给定的是一个字符串(输入行),其中包含多个(不可预测的数字)字符。 在这个字符串中,我想从一组字符中找到第一个匹配项 例如: -- ASCII value(hex) of keyboard keys. #define KEY_UP "\x41" #define KEY_DOWN "\x42" #define KEY_RIGHT "\x43" #define KEY_LEFT "
-- ASCII value(hex) of keyboard keys.
#define KEY_UP "\x41"
#define KEY_DOWN "\x42"
#define KEY_RIGHT "\x43"
#define KEY_LEFT "\x44"
-- terminal object is defined and created
function terminal:receive()
-- Set buffer and shorthand to self.port.read
local read = function() return self.port:read() end
local received = ""
while true do
-- Read Input
local line = read()
if ( not line ) then break end
received = received .. line
-- Search for the key.
-- Don't search in line, due different baudrates might not
-- Get the entire digit at once.
if ( received:find( KEY_UP ) ) then
return KEY_UP
elseif ( received:find( KEY_DOWN ) ) then
return KEY_DOWN
... and so on
end
end
end
我的例子中的解决方案肯定有点慢。想出更高性能的解决方案并不难。但是最有效的解决方案是什么呢?您可以制作一个包含所有要查找的字符的模式。然后,您可以捕获结果并返回它
如果您要查找的字符之间没有任何优先级顺序,则此操作有效。由于所有匹配项都是一个字符长,您可以使用set
[]
来匹配和捕获()
以查看匹配的内容
#define KEY_UP "\x41"
#define KEY_DOWN "\x42"
#define KEY_RIGHT "\x43"
#define KEY_LEFT "\x44"
-- assemble pattern once for performance
local KEY_pattern = "([" .. KEY_UP .. KEY_DOWN .. KEY_RIGHT .. KEY_LEFT .. "])"
-- ............... skipped ...............
local match_start, match_end, match_content = received:find(KEY_pattern)
if ( match_content ) then
return match_content
end
你用过剖析器吗?您确定模式匹配部分是这里的性能瓶颈吗?可能不是,但这是另一个问题。我只是第一眼就关心匹配,因为我正在搜索大约40个键。如果匹配是第一个关键点之一,那么它肯定非常快,接收过程可能是瓶颈。但是,如果没有匹配项,那么就有40个:find()s,这需要几个刻度。为什么要先把字符串放在一起,然后再对其进行解析?为什么不在读取输入后立即检查键?@Sempie:如果将所有键放在一个模式中,则可以使用一个
:find()
,而不是40。。。