解析大字符串的最快方法(multithreading)

我即将开始一个项目,它将获取文本块,将大量数据解析为某种对象,然后可以对其进行序列化,存储和统计/数据收集。 这需要尽可能快,因为我需要启动超过10,000,000个文本块,并且每天将获得100,000个成千上万的文本。

我在具有12个核心+超线程的系统上运行它。 我也可以访问/了解CUDA编程,但对于字符串的东西认为它不合适。 从每个字符串我需要解析大量的数据,其中一些我知道确切的位置,有些我不知道,需要使用正则表达式/智能的东西。

所以考虑这样的事情:

object[] parseAll (string [] stringsToParse) { parallel foreach parse( string[n] ) } object parse(string s) { try to use exact positions / substring etc here instead of regex's } 

所以我的问题是:

  • 使用正则表达式来减少多少速度。
  • .NET会比其他语言慢得多吗?
  • 我可以做什么样的优化(如果有的话)来最大化并行性。
  • 还有什么我还没考虑过吗?

谢谢你的帮助! 对不起,如果这是漫长的啰嗦。

使用正则表达式来减少多少速度。
如果您正在寻找一个精确的字符串,substr会更快。 然而,正则表达式被高度优化。 它们(或至少部分)被编译为IL,您甚至可以使用Regex.CompileToAssembly将这些编译版本存储在单独的程序Regex.CompileToAssembly 。 有关更多信息,请参见http://msdn.microsoft.com/en-us/library/9ek5zak6.aspx 。

你真正需要做的是做测量。 使用类似Stopwatch东西是迄今为止validation一个或另一个代码构造是否更快的最简单方法。

我可以做什么样的优化(如果有的话)来最大化并行性。
使用Task.Factory.StartNew ,您可以安排在线程池上运行的任务。 您还可以查看TPL(任务并行库,其中Task是其中的一部分)。 这有很多构造可以帮助您并行化工作,并允许像Parallel.ForEach()这样的构造在多个线程上执行迭代。 有关更多信息,请参见http://msdn.microsoft.com/en-us/library/dd460717.aspx 。

还有什么我还没考虑过吗?
使用大量数据会对您造成伤害的一个原因是内存管理。 需要考虑的一些事项:

  • 限制内存分配:尝试为单个文档重复使用相同的缓冲区,而不是在只需要一个部分时复制它们。 假设您需要处理从char 1000到2000开始的范围,不要将该范围复制到新缓冲区中,而是将代码构造为仅在该范围内工作。 这将使您的代码更复杂,但它可以节省您的内存分配;

  • StringBuilder是一个重要的类。 如果您还不知道,请看看。

我不知道你在这里做了什么样的处理,但是如果你每天都在谈论成千上万的字符串,那么这似乎是一个非常小的数字。 假设您每天要处理100万个新字符串,并且可以完全执行12个Xeon核心中的10个。 那是每天每个核心100,000个字符串。 一天有86,400秒,所以我们每串说0.864秒。 这是很多解析。

我会回应@Pieter提出的建议,特别是他建议进行测量以了解处理所需的时间。 你最好的选择是获得一些东西并开始工作, 然后在你需要的时候弄清楚如何让它变得更快。 我想你会经常不需要做任何优化就会感到惊讶。 (我知道这对于优化向导来说是异端,但处理器时间很便宜,程序员时间也很昂贵。)

使用正则表达式来减少多少?

这完全取决于你的正则表达的复杂程度。 正如@Pieter所说,如果你正在寻找一个字符串, String.Contains可能会更快。 如果要查找常量字符串,也可以考虑使用String.IndexOfAny 。 除非您正在寻找无法表示为常量字符串的模式,否则不需要正则表达式。

.NET会比其他语言慢得多吗?

在处理器密集型应用程序中,.NET可能比本机应用程序慢。 有时。 如果是这样,通常在5%到20%的范围内,最常见的是在7%到12%之间。 那只是代码执行的代码。 您必须考虑其他因素,例如您用其他语言构建程序所需的时间以及在本机应用程序和系统其余部分之间共享数据的难度。

谷歌最近宣布了它的内部文本处理语言(这似乎是为大量并行处理而制作的Python / Perl子集)。

http://code.google.com/p/szl/ – Sawzall。

如果您想在C#中进行快速字符串解析,您可能需要考虑查看新的NLib项目。 它包含字符串扩展,以便于以各种方式快速搜索字符串。 例如,IndexOfAny(string [])和IndexOfNotAny。 它们也包含带有StringComparison参数的重载。