2014-10-04 53 views
0

我正在处理文本文档解析应用程序。无法找出正确的数据结构和正确的方法在这种情况下解析文本

  1. 文件包含 页的ArrayList:

    文档的设计图中的figure

    下面是如何解析正在做的是,如图所示。

  2. 每个页面都有一个Map<float, List<Character>>

float值包含一个字符位置的y轴值,因此一个key和字符包含其它信息。

解析是通过第三方库逐字符完成的。如果需要更多信息,请添加评论。

现在,在解析时,我创建了两个ExecutorService线程池,一个用于页面,另一个用于填充地图。

我最初创建一个文档并将每个页面传递给page parser作为可运行到ExecutorService。它依次将empty map传递给文本解析器。

文本解析器检查map是否有键值 如果是,它会将字符添加到列表或新列表中,这是必要的。

这里的问题是,这个任务可以同时完成所有页面以加速执行。但是我无法处理这个数据结构,因为所有的线程如果正常解析,并且如果使用Collections.synchronizedMap以同步方式完成,则需要花费大量时间。

此外,我维护Future对象的两个不同列表来检查线程是否完成。

请提供宝贵的改进建议和并发执行以加快执行速度。

+1

开始以最简单的方式在单个线程中执行此操作,并查看它是否足够快。如果不是,测量什么需要时间,并尝试优化。同时做大量的事情并不是加速做事的神奇方式。它具有由于上下文切换,同步,增加的复杂性等原因而产生的固有成本。 – 2014-10-04 19:53:43

+0

Nizet我同意但是当你解析一个大约5k页面的文档时,我必须等待一分钟。单线程肯定不是这个解决方案。一旦地图准备就绪后,还会进行进一步的计算 – 2014-10-04 19:58:28

+1

然后尝试采用简单的分工策略。您有5000页,4个CPU内核。因此,创建4个线程,每个线程解析1250个页面,并在完成后汇总结果。 – 2014-10-04 20:02:21

回答

2

如果每个页面都有自己的Map<float, List<Character>>,那么永远不会有多个线程处理单个页面 - 那么您将不需要同步对Map的访问或使用并发Map实现。正如JB Nizet在评论中所建议的那样,您可以静态分配工作人员中的网页;另一种选择是将所有页面放在ConcurrentLinkedQueue中,并让工作人员poll为解析页面的队列,当队列为空时(poll返回null)终止。无论哪种方式,您只需要一个ExecutorService,因为每个工作人员都负责解析和地图填充。

相关问题