计算RichTextbox中所有单词的最有效方法是什么?
-
19-09-2019 - |
题
我正在编写文本编辑器,需要提供现场单词计数。现在,我正在使用此扩展方法:
public static int WordCount(this string s)
{
s = s.TrimEnd();
if (String.IsNullOrEmpty(s)) return 0;
int count = 0;
bool lastWasWordChar = false;
foreach (char c in s)
{
if (Char.IsLetterOrDigit(c) || c == '_' || c == '\'' || c == '-')
{
lastWasWordChar = true;
continue;
}
if (lastWasWordChar)
{
lastWasWordChar = false;
count++;
}
}
if (!lastWasWordChar) count--;
return count + 1;
}
我已经设置了它,以便单词计数在第十秒的每一秒钟都在RichTextbox的文本上运行(如果选择启动与上次方法播放的情况不同)。问题在于,在处理很长的文件时,单词计数会慢。为了解决这个问题,我正在考虑只在当前段落上运行单词计数,每次记录单词计数,并将其与上次count count运行的单词计数进行比较。然后,将两者之间的差异添加到总单词计数中。这样做会导致许多并发症(如果用户粘贴,如果用户删除了段落,ECT。)这是改善我的单词计数的逻辑方式吗?还是我不知道哪些东西会使它变得更好?
编辑:在另一个线程上运行单词计数是否有效?我对线程的了解不多,会研究。
我使用的示例文本:
解决方案
您可以根据白空间进行更简单的单词计数:
public static int WordCount(this string s)
{
return s.Split(new char[] {' '},
StringSplitOptions.RemoveEmptyEntries).Length;
}
MSDN提供了此示例, ,应该在大文件上给您准确的单词计数。
其他提示
您还可以使用一个非常简单的正则态度,该正则认为至少一个单词字符和/或撇号来捕获收缩:
public static int WordCount(this string s)
{
return Regex.Matches(s, @"[\w']+").Count;
}
这将返回2141匹配(在这种情况下,这实际上比单词更正确,因为单词将单个星号计算为句子中的单词“通过用手指刺a *”)。
您的方法实际上比提议更快 String.Split
方法,实际上在x86上快了近三倍,x64的速度快两倍以上。我怀疑jit弄乱了您的时间,始终运行您的微晶测量,因为JIT会占据 绝大多数 在您的第一次跑步期间的时间。因为 String.Split
已经不需要,不需要将其编译到本机代码,因此似乎会更快。
更不用说它也更准确 String.Split
将在这里计算7个单词:
测试::这是一个测试
这也有道理 String.Split
没有执行任何魔法,如果创建许多字符串的数组比简单地迭代字符串中的单个字符更快,我会感到非常惊讶。当我尝试时,在弦上供应弦显然已经得到了高度优化 unsafe
指针算术,实际上比简单的一点慢一点 foreach
. 。我真的怀疑有什么方法可以更快地执行此操作,除了明智地了解文本中的哪些部分需要单词计数。