计算richtextbox中所有单词的最有效方法是什么?

我正在写一个文本编辑器,需要提供一个实时字数。 现在我正在使用这个扩展方法:

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,每次记录单词计数,并将其与上次单词计数运行时的单词计数进行比较。 然后它会将两者之间的差异添加到总字数中。 这样做会导致许多复杂情况(如果用户粘贴,如果用户删除了一个段落,等等。)这是一种合理的方法来改善我的字数吗? 或者是否有一些我不知道哪些会使它变得更好?

编辑:它可以在不同的线程上运行单词计数吗? 我不太了解线程,会研究。

我使用的示例文本:

您可以根据空白区域进行更简单的字数统计:

 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个匹配(在这种情况下实际上比Word更正确,因为Word将单个星号计为句子中的一个单词“用手指刺伤*”)。

你的方法实际上比提出的String.Split方法更快,在x86上快了近三倍,在x64上快了两倍多。 我怀疑JIT正在弄乱你的时间,总是运行你的微基准测试两次,因为JIT将在你第一次运行时占据绝大多数时间。 并且因为String.Split已经NGEN,所以它不需要编译为本机代码,因此看起来会更快。

更不用说它也更准确了, String.Split在这里算7个字:

测试::这是一个测试

它也是有道理的, String.Split不执行任何魔法,如果创建一个包含许多字符串的数组比简单地迭代字符串中的单个字符更快,我会感到非常惊讶。 当我尝试使用unsafe指针算法时,对字符串的预告显然已经高度优化,它实际上比简单的foreach慢一点。 我真的怀疑有没有办法更快地做到这一点,除了聪明你的文本中的哪些部分需要字数。