4

我必须处理大约200 万个文本文件并在那里生成三元组。

假设我有一个txt文件xyz.txt(200万输入的文件之一),处理如下:

start(xyz.txt)---->module1(xyz.tpd)------>module2(xyz.adv)-------->module3(xyz.tpl)

建议我一个逻辑或概念,以便我可以在 x64 4GB Windows 系统上以优化的方式更快地处理。

module1(working):它使用调用解析器的 .bat 文件解析 txt 文件,它是一个单独的系统线程,15 秒后它再次开始解析另一个 txt 文件,依此类推....

module2(working):它接受.tpd文件作为输入并生成.adv文件。module3(工作):它接受.adv文件作为输入并生成.tpl(三元组)。

我应该从 txt 文件还是在其他点开始线程..?我担心如果我的 CPU 卡在上下文切换中。

任何人都可以有更好的逻辑,以便我可以尝试..!?

4

5 回答 5

4

使用ThreadPoolExecutor。调整它的参数,如活动线程数和其他参数以适应您的环境和系统。

于 2013-06-04T07:08:41.110 回答
4

最重要的是,您必须编写程序,对其进行分析,然后查看瓶颈在哪里。磁盘 I/O 操作很可能成为瓶颈,再多的多线程也无法解决您的问题。

在这种情况下,使用两个(三个?四个?)单独的硬盘驱动器可能会比最好的多线程解决方案产生更多的速度增益。

此外,一般规则是,只有当您有工作代码并且您真正知道要优化什么时,您才应该优化您的应用程序。简介,简介,简介。

写的时候考虑到未来的多线程优化就OK了;架构应该足够灵活,以允许未来的优化。

于 2013-06-04T07:11:46.860 回答
1

这里没有太多关于你的硬件环境的介绍;但基本解决方案是使用固定大小ExecutorService,其中大小首先是执行单元的数量:

private static final int NR_CPUS = Runtime.getRuntime().availableProcessors();

// Then:

final ExecutorService executor = Executors.newFixedThreadPool(NR_CPUS);

然后,对于每个文件,您可以创建一个Runnable来处理它,并使用它的方法将它提交到线程池.execute()

注意.execute()是异步的;如果提交的runnable现在不能运行,它将被排队。

于 2013-06-04T07:20:24.680 回答
0

..听起来像是数据集成所需的典型批处理应用程序。虽然,我不打算在不完全了解您的需求的情况下抛出超链接,但是,您可能需要一个应该在单个 VM 中工作的解决方案,并且在一段时间内您希望将解决方案扩展到多个 VM/机器。也许我们一开始就没有处理 PB 的数据.. 尝试Spring Batch不仅可以解决给定上下文中的问题,您还将学会构建您的想法(想想词汇!)以解决类似的问题..

于 2013-06-04T09:10:30.960 回答
0

作为起点,我将创建一个 IO 线程和一个 CPU 线程池。IO 线程读取文本文件并将offer它们发送到 a BlockingQueue,而 CPU 线程take化来自 的文件BlockingQueue并处理它们。然后分析应用程序以查看您应该使用多少 CPU 线程来跟上 IO 线程的速度(您也可以动态确定这一点,例如从一个 CPU 线程开始并在BlockingQueue超过一个阈值,可能是 20 个文件)。您可能会发现只需要一个 CPU 线程来跟上 IO 线程,在这种情况下,您的程序是 IO 绑定的,您需要将文本文件彼此相邻放置在磁盘上(这样您可以对除第一个文件以外的所有文件使用顺序读取)或将它们放在单独的磁盘上以加快应用程序的速度;一个想法是将文件压缩在一起并用 a 读取它们ZipInputStream- 这将减少读取文件时的磁盘寻道次数,也将减少您需要读取的数据量

于 2013-06-04T13:39:04.737 回答