我有一个RichTextBox,一旦用户加载文件,我的程序就会继续扫描整个文件,以便更改某些单词的颜色。这是我的代码:
static Regex cKeyWords = new Regex(@"\b(?=[a-gilr-w])(?:
s(?:hort|i(?:gned|zeof)|t(?:atic|ruct)|witch) | c(?:ase|har|on(?:st|tinue)) |
e(?:lse|num|xtern) | i(?:f|nt) | f(?:loat|or) | d(?:o|efault|ouble) | un(?:ion|signed) |
re(?:gister|turn) | vo(?:id|latile) | while | break | long | typedef | auto | goto
)\b",
RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace);
...
programTextBox.Enabled = false;
int selectStart = this.programTextBox.SelectionStart;
programTextBox.SuspendLayout();
MatchCollection matches = cKeyWords.Matches(programTextBox.Text);
foreach (Match match in matches)
{
if (match.Index == 0)
programTextBox.Select(match.Index, match.Length/* - 1*/);
else
programTextBox.Select(match.Index + 1, match.Length - 1);
programTextBox.SelectionColor = Color.Blue;
}
programTextBox.Select(selectStart, 0);
programTextBox.SelectionColor = Color.Black;
programTextBox.Enabled = true;
programTextBox.ResumeLayout();
问题:我的代码需要大约5秒半的时间来扫描并更改包含200,000个字符的文件中所有关键字的颜色。
我之前被告知我不应该使用正则表达式那样的东西,但经过几次测试后我发现了:MatchCollection matches = cKeyWords.Matches(programTextBox.Text);
只需要大约0.1秒并删除
programTextBox.SelectionColor = Color.Blue;
将代码的总执行时间从5.5秒减少到大约0.3秒
如何?为什么?最重要的是:我能做些什么?
答案 0 :(得分:0)
您是否尝试过this?
这阻止了绘画,实际上似乎正确地阻止了它。我只有一个小的测试文件可以通过它,但它似乎工作得很好。
答案 1 :(得分:0)
不要自己进行语法高亮,而是尝试使用ICSharpCode.TextEditor,SharpDevelop IDE的语法高亮编辑器。
答案 2 :(得分:0)
我维护VS Code的C ++语法突出显示器,该突出显示的single regex patterns长度超过9000个字符。您编写的正则表达式非常有效,可能效率也很高(删除前瞻功能比分解单词更有用)。
这是一个基本的UI问题。用户界面很慢,VS Code之类的东西在一秒钟之内无法突出显示200,000行。很好,因为用户永远不会一次查看200,000行。因此,Atom / VS Code会智能地仅对可见行调用等效的programTextBox.SelectionColor = Color.Blue;
。与Sublime和其他文本编辑器相同;他们只会更新您看到的内容和已更改的内容,因为与GUI混淆非常昂贵。
执行Sriram Sakthivel的评论而不是更新UI约100,000次(不确定为什么他没有做出回答)“在循环之前暂停绘画,并在循环之后立即继续绘画。RichTextBox syntax highlighting in real time--Disabling the repaint或最好还是找到一个支持语法突出显示的控件。有几个可用的开源库。”
这实际上是用于每个文本编辑器的相同解决方案。