繁体   English   中英

将 memory 中的大量数据写入文件的最快方法是什么?

[英]What is the fastest way to write a large amount of data from memory to a file?

我有一个程序生成大量数据并将其放入队列中进行写入,但问题是它生成数据的速度比我目前正在写入的速度快(导致它达到最大 memory 并开始变慢)。 顺序无关紧要,因为我打算稍后解析文件。

我环顾四周,发现了一些帮助我设计当前流程的问题(但我仍然觉得它很慢)。 到目前为止,这是我的代码:

//...background multi-threaded process keeps building the queue..
FileWriter writer = new FileWriter("foo.txt",true);
        BufferedWriter bufferWritter = new BufferedWriter(writer);
        while(!queue_of_stuff_to_write.isEmpty()) {
            String data = solutions.poll().data;
            bufferWritter.newLine();
            bufferWritter.write(data);
        }
        bufferWritter.close();

我对编程还很陌生,所以我可能会评估这个错误(可能是我使用 EC2 时的硬件问题),但是是否可以非常快速地将队列结果转储到文件中,或者如果我的方法还可以,我可以改进它不知何故? 由于顺序无关紧要,在多个驱动器上写入多个文件是否更有意义? 线程会使其更快吗?等等。我不确定最好的方法和任何建议都会很好。 我的目我假设它将是一个 15gig+ 文件)。

在文本文件 Java 中写入大量数据的最快方法(意识到我应该使用缓冲写入器) 并发文件写入 Java on Windows (让我明白也许多线程写入不是一个好主意)

查看该代码,想到的一件事是字符编码。 您正在编写字符串,但最终,流中的字节是 go。 引擎盖下的编写器字符到字节编码,它在处理写入的同一个线程中执行。 这可能意味着有时间花费在延迟写入的编码上,这可能会降低写入数据的速率。

一个简单的更改是使用byte[]队列而不是String ,在推送到队列的线程中进行编码,并让 IO 代码使用BufferedOutputStream而不是BufferedWriter

这也可以减少 memory 消耗,如果编码文本平均每个字符占用少于两个字节。 对于拉丁文本和 UTF-8 编码,这通常是正确的。

但是,我怀疑您生成数据的速度可能快于您的 IO 子系统可以处理的速度。 您将需要使您的 IO 子系统更快 - 通过使用更快的子系统(如果您使用的是 EC2,可能租用更快的实例,或者写入不同的后端 - SQS vs EBS vs 本地磁盘等),或者通过组合几个 IO 子系统以某种方式并行在一起。

是的,在多个驱动器上写入多个文件应该会有帮助,如果没有其他东西同时写入这些驱动器,性能应该与驱动器数量成线性关系,直到 I/O 不再是瓶颈。 您还可以尝试其他一些优化来进一步提高性能。

如果您正在生成巨大的文件而磁盘根本跟不上,您可以使用 GZIPOutputStream 来缩小输出——这反过来会减少磁盘 I/O 的数量。 对于非随机文本,您通常可以期望压缩率至少为 2x-10x。

    //...background multi-threaded process keeps building the queue..
    OutputStream out = new FileOutputStream("foo.txt",true);
    OutputStreamWriter writer = new OutputStreamWriter(new GZIPOutputStream(out));
    BufferedWriter bufferWriter = new BufferedWriter(writer);
    while(!queue_of_stuff_to_write.isEmpty()) {
        String data = solutions.poll().data;
        bufferWriter.newLine();
        bufferWriter.write(data);
    }
    bufferWriter.close();

如果您正在输出常规(即重复)数据,您可能还需要考虑切换到不同的 output 格式——例如,数据的二进制编码。 根据数据的结构,将其存储在数据库中可能更有效。 如果你正在输出 XML 并且真的想坚持使用 XML,你应该查看二进制 XML格式,例如 EXI 或 Fast InfoSet。

我想只要您从计算中生成数据并且不从其他数据源加载数据,写入总是比生成数据慢。

您可以尝试在多个线程中将数据写入多个文件(不在同一个文件中 -> 由于同步问题)(但我想这不会解决您的问题)。

您是否可以等待应用程序的写入部分完成其操作并继续计算?

另一种方法是:清空队列吗? solutions.poll() 会减少您的解决方案队列吗?

使用多个线程写入不同的文件是个好主意。 此外,您应该考虑设置 BufferedWriters 缓冲区大小,您可以从构造函数中执行此操作。 尝试使用 10 Mb 缓冲区进行初始化,看看是否有帮助

暂无
暂无

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

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