Java中的性能/内存,用于生成多个文件的数据

时间:2015-11-19 06:52:01

标签: java performance memory

问题在于: 1.需要为3个文件生成1.000.000个条目/文件(csv_extension)。 1. 3个文件之间的数据连接如下: 文件1 - 会话 文件2 - 工作流程 文件3 - 步骤

文件2需要包含文件1中生成的Session_ID字段,文件3需要文件2中生成的Workflow_ID字段,以便它们是它们之间的链接。 会话包含工作流程,工作流程包含步骤。

如何在没有性能和内存影响的情况下在生成时执行此操作?

谢谢!

3 个答案:

答案 0 :(得分:0)

您应该使用streams(输入和输出)来处理文件(大数据)而不会占用太多内存。

Here's一篇不错的文章。

简化示例:

FileReader in = null; 
FileWriter out = null; 
try { 
    in = new FileReader("input.txt"); 
    out = new FileWriter("output.txt"); 
    int c; 
        while ((c = in.read()) != -1) { 
            out.write(c); 
        } 
}
finally { 
    if (in != null) { 
        in.close(); 
    } 
    if (out != null) { 
        out.close(); 
    } 
}

答案 1 :(得分:0)

自然地做任何事都会带来性能/内存影响,但无论如何......

此问题最明显的尴尬部分是CSV文件。它是一种纯文本格式,可以有效地将您输出的每个字段渲染为可变大小的块。当您无法利用有关正在大量写入或读取的内存块的固定大小假设时,很难在文件I / O(或任何类型的内存I / O)中获得最佳性能。

将此对比,例如,将一百万个连续浮点值输出到二进制文件,其中每个文件将写入一个32位块。这可能发生得非常快(毫秒,例如)

除此之外,以明文形式输出涉及到线下的词法转换,即使不考虑内存中发生的事情,也会造成更大的CPU压力。

没有深入了解细节,在分析之前我们不应该这样做(大多数微优化最好保存在测量后的后见之明),最初在这里利用的最有效的方法是并发

虽然你有这些文件间依赖关系,但是临时存储在内存中的百万条目应该相对便宜(假设每个条目同样聚合了一百个元素或类似的东西)。您应该能够在易失性存储器中计算和存储这种相互依赖的数据,而不涉及直接的文件间依赖性。

由于顺序依赖性,计算相互依赖的数据实际上是一个连续问题,因此必须在单个线程中执行(除非您可以在每个条目级别的会话/工作流/步骤中同时执行此操作,这一点你可以只是并行化条目的计算。)

在易失性存储器中计算后,您可以并行化这三个文件中每个文件的输出。

除此之外,在这个初始阶段可能只是确保您使用一个有效的I / O API和一个相当紧凑的数据表示,并具有良好的参考位置,以便存储在易失性存储器中。

答案 2 :(得分:0)

在性能方面,您正在对3个不同的文件进行大量I / O.

如果您只使用普通FileWriterFileOutputStream,则可能会降低处理速度。 主要原因是您只是编写一小块数据(一行CSV),而是经常写入磁盘。

因此,我建议使用缓冲区通过编写较大的块来加快速度较慢的I / O,但BufferedOutputStreamBufferedWriter包裹FileWriter或{{3}的频率较低}}

合理的缓冲区大小可能是64 KB。 假设硬盘上的簇大小为4 KB,这将缓存16个数据块,然后立即将它们写入磁盘。

就内存影响而言,您应该确保在每个处理步骤中只处理一条记录并将其写入,然后将链接的记录写入磁盘,而不保留以供日后使用。