解析大字符串的最快方法(多线程)

时间:2010-11-06 18:31:05

标签: c# regex parsing string parallel-processing

我即将启动一个项目,该项目将获取文本块,将大量数据解析为某种对象,然后可以对其进行序列化,存储和统计/数据收集。这需要尽可能快,因为我有>我需要开始的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会比其他语言慢得多。
  • 我可以采取哪种优化(如果有的话)来最大化并行性。
  • 我还没有考虑过的其他事情?

感谢您的帮助!对不起,如果这是长篇大论。

4 个答案:

答案 0 :(得分:4)

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

您真正需要做的是执行测量。使用类似Stopwatch之类的东西是验证一个或另一个代码构造是否运行得更快的最简单方法。

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

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

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

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

答案 1 :(得分:1)

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

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

  

正则表达式使用正则表达式减慢了多少?

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

  

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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