2013-03-23 50 views
2

我正在使用ANTLRv4生成的分析器来处理具有多个核心的计算机上的大量文件。为了获得一些额外的速度,我想并行处理文件。并行运行多个ANTLR4词法分析器/解析器实例

为了检查解析器性能是否受CPU限制,我将这些文件拆分成组并使用独立进程进行解析,每个独立进程在专用JVM实例中运行相同的解析器。这大大提高了性能。

这鼓励我尝试使用多线程代替进程,但是,没有成功。我创建了两个工作线程,每个线程都有自己的解析器实例,词法分析器和文件流。返回的结果是正确的,但是,使用两个线程实际上比使用一个稍长。

为了确保我正确使用线程并确保JVM安装没有问题,我暂时用计算斐波那契数列的代码替换了解析代码:在这种情况下,使用多个线程会导致性能下降,增加。

分析此行为,我发现使用多个解析线程时,没有任何CPU达到高使用率。看起来线程正在争夺一些共享资源。

考虑看看ANTLR源代码,我发现在ParserATNSimulator.java以下注释:

“都一样解析器份额的情况下,通过一个静态字段相同的决定DFA的每个实例都有自己的ATN但它们共享相同的decisionToDFA字段,它们还共享一个PredictionContextCache对象,以确保所有PredictionContext对象在DFA状态之间共享,这造成了很大的差异。

我想知道对这些共享资源的同步访问是否会导致性能问题。如果是这样,是否有可能创建这些资源的唯一实例呢?或者甚至可能有更简单的解决方案?

在此先感谢!

的Fabian

回答

5

的ANTLR 4运行时的参考版本被设计使用多个解析器线程时是安全(只要多个解析器实例被使用)。我维护ANTLR 4的备用(非官方)分支,以不同的方式实现核心算法,以提高多线程场景中的性能。

这个分支暴露出部分地区略有不同的API,所以它不是一个下拉更换为4.0版本的ANTLR 4.

https://github.com/sharwell/antlr4/tree/optimized

+0

谢谢您的回答。核心算法的优化版本是否可能在某些时候被整合到官方版本中? – user2202828 2013-03-24 13:18:24