繁体   English   中英

JAVA-如何加快顺序任务

[英]JAVA - How to speed up a sequential task

我有一个Java应用程序,该应用程序当前在循环中逐行分析输入文件,并且每一行(通过特定的API)在输出文件中写入一行。

行的写入顺序很关键 (行带有时间戳)。 鉴于此,我选择了在主线程中执行整个任务,但是性能却很糟糕:我不知道有其他方法可以最大化性能,而不会利用多线程,但是由于顺序关键性我认为没有机会雇用它。 顺便说一句,我不是并行执行专家,也许我不知道有没有办法使用它:是这样吗?

PS:(75%的时间都花在写操作上,因此瓶颈不在文件解析中)

PPS:应用程序必须在本地计算机上运行。

如果您发现执行中花费的时间最多是写输出,那么这已经很好地表明了最大的速度提高在哪里。 在尝试优化之前,您已经正确地进行了测量。

第一步是确保FileWriter (或FileOutputStream ,无论使用哪种)都包装在具有足够大缓冲区的BufferedWriterBufferedOutputStream 这样,Java可以将输出放置在缓冲区中,并且仅在输出填满时才将其刷新到文件中。 输出量不会改变,但会分配给更少的I / O调用。

如果这样做没有效果,请查看有关java.nio包中的类的用法的教程。 Java SE 7中添加了Java 1.4中引入的该API和提供文件系统功能的名为NIO.2的扩展。这些API提供了非阻塞I / O。 非阻塞I / O背后的思想是,线程倾向于在传统I / O操作中花费大量时间,等待底层OS和硬件完成读写操作,同时不执行任何有用的工作。 使用非阻塞I / O,您可以将输出放置到缓冲区中,并以异步方式将其写出,这意味着write调用会立即返回,并且可以在系统调用完成传输时继续执行其他有用的工作。 这与常规的BufferedWriter或BufferedOutputStream不同,后者提供内存中的缓冲区,但是一旦刷新缓冲区,仍会阻止将其写出。

使用非阻塞I / O,您的应用程序可以在写入输出时从输入和/或过程中获取更多数据,从而实现更好的并行处理。 但是,如果输出端存在很大的瓶颈,以至于读取和处理总是随着写入而“赶上”,从而淹没了输出通道的缓冲区,那么输出仍将是限制因素。 毕竟,最后所有输出都必须写入文件。

在确保输出保持可预测顺序的同时执行并行输出的一种方法是使用内存映射文件。 您将为此使用java.io.RandomAccessFile ,也可以将其与java.nio结合使用以进行异步写入。 然后,您可以并行写入文件的不同部分。 此处的缺点是,对于输出的每个部分,您都需要确保其具有特定的长度。 除了某些非常特定的用例(如定长文本或某些二进制格式)外,通常情况也不妙。

最后,可以并行处理输入,然后确保不管输入的哪个部分首先被处理,仍然以正确的顺序写出输入是可行的。 您只需要在输出中加入一些元数据(例如,通过将其包装在一些帮助器类中)来标识顺序,并让输出不写乱序。 某些库可能提供有用的东西,但是带有对象的优先级队列可以包装输出并具有序列号就足够了。 这是在集成模式中称为重新排序器的模式

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM