我有一个带有文本框的应用程序。用户在此框中输入文本。
我在该文本框中的OnKeyUp事件中触发了以下功能
private void bxItemText_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
// rules is an array of regex strings
foreach (string rule in rules)
{
Regex regex = new Regex(rule);
if (regex.Match(text.Trim().ToLower()))
{
// matched rule is a variable
matchedRule = rule;
break;
}
}
}
我在rules
中有大约12个字符串,尽管这可能会有所不同。
一旦文本框中文本的长度超过80个字符,性能就会开始下降。在100个字符后输入一个字母需要一秒钟才能显示出来。
如何优化此功能?我应该每隔3个KeyUp匹配一次吗?我应该完全放弃KeyUp并且每隔几秒钟自动匹配一次吗?
答案 0 :(得分:4)
如何优化此功能?我应该每隔3个KeyUp匹配一次吗?我应该完全放弃KeyUp并且每隔几秒钟自动匹配一次吗?
我会选择第二个选项,即放弃KeyUp
并每隔几秒触发一次验证,或者更好地在TextBox
失去焦点时触发验证。
另一方面,我应该建议事先缓存正则表达式并编译它们,因为它似乎是一遍又一遍地使用它们,换句话说,而不是将规则存储为该数组中的字符串,你应该存储它们在添加或加载时作为编译的正则表达式对象。
答案 1 :(得分:1)
每次使用static
方法调用而不是创建新对象, static
调用使用 caching
功能:{ {3}}
这将是性能的重大改进,然后您可以提供正则表达式(规则),以查看是否可以在正则表达式中进行某些优化。
其他资源:
答案 2 :(得分:0)
将字符串与Regex级别的字符串组合将比代码中的foreach更快。 Combining two Regex to one
答案 3 :(得分:0)
如果您需要每个新符号的模式确定,并且您关心性能,那么最终状态机似乎是最佳选择...... 这是一个更难的方式。您应该为允许的下一个符号的每个符号列表指定。 如果可能的话,OnKeyUp你只需走下一个州。并且您将拥有当前匹配的输入文本的模式数量。 一些有用的参考资料,我可以找到:
答案 4 :(得分:0)
每次都不需要创建新的正则表达式对象。如果之前使用(自.Net 2),也使用静态调用将缓存模式。以下是我将如何重写它
matchedRule = Rules.FirstOrDefault( rule => Regex.IsMatch(text.Trim().ToLower(), rule))
;
答案 5 :(得分:0)
鉴于您似乎匹配关键字,您是否可以仅对已编辑的文本的当前部分(即在光标附近)执行匹配?可能很难设计,特别是对于粘贴或撤消等操作,但可以获得巨大的性能提升。
答案 6 :(得分:-1)
预编译你的正则表达式(使用RegexOptions.Compiled
)。另外,您可以通过扩展正则表达式使Trim
和ToLower
多余吗?您为每条规则运行Trim
和ToLower
一次,即使您无法完全消除它们,效率也很低
你可以尝试让你的规则互相排斥 - 这应该加快速度。我做了一个简短的测试:匹配以下
“猫|汽车|驾驶室|盒|气球|键”
可以通过像这样编写来加速
“CA(T | R | B)| B(牛| alloon | utton)”