我实现了一个需要扫描潜在长字符串(例如,高达200kB)的解析器,并且需要尽可能高效。字符串显示可能包含层次结构的结构(为了清楚起见,我们假设它是类似JSON的字符串)。
扫描过程实现为FSM(有限状态机),因此扫描过程可以是捕获或绕过字符,其中两个选项都作为运行的循环,直到找到任何一系列可能的终止,或者测试的字符不在列表中。
例如,如果扫描正在某个数字上运行,它将一直持续到找到不在列表'0123456789.+-'
中的字符。如果扫描超过字符串,则当测试字符位于列表'"\''
中时,它将终止(其中\
是'
的转义)。当然,还有其他可以检查的列表。
所以,逻辑是(示意性地):
IF <scan till char NOT IN LIST>
IF <check if character in list>
BREAK ;
ELSE -- <scan while char in list>
IF <check if character NOT in list>
BREAK ;
请务必注意,测试列表是动态构建的。
我到目前为止测试了以下选项:
使用函数CHARINDEX
,如果它返回0
,则测试的字符不在列表中,否则就是,
拆分可能的字符列表,然后插入本地表格,然后使用IF <test char> IN (SELECT ONE_CHAR FROM @_local_Table)...
构建格式为SET @_Command = 'SELECT CASE WHEN ''x'' in (''a'',''b'',''c'') THEN 1 ELSE 0 END'...
我检查了所有三种选择,虽然性能存在一些差异,但它们都没有达到所需的响应时间。同样,在扫描字符串时,可能需要执行此检查数千次。
我非常感谢有关如何以不会影响解析器整体响应时间的方式实现此部分的建议。
答案 0 :(得分:1)
我建议您使用CLR存储过程。它允许SQL Server执行.Net代码。 只需创建一个dll项目,并使用[SqlProcedure]或[SqlFunction]属性编写一个方法。
[SqlProcedure]
public static int UserDefineFunction(string logstring)
{
//your code to do the work
}
这可能会提高性能。