从java中的大文件中读取和处理字符串的最快方法?

时间:2015-08-15 19:02:24

标签: java

我在文件中有一个大字符串(它的编码数据,我的自定义编码),我想读它并将其处理成我的特殊格式(解码)。我想知道我能以最快的方式获得最终格式。我想到了一些方法,但不确定哪种方式最好。

1)读取1行中的整个字符串,然后处理该字符串。

2)在阅读时,从文件和进程中逐个字符读取。

有人可以帮忙吗? 感谢

3 个答案:

答案 0 :(得分:4)

进程可能是IO绑定而不是CPU绑定所以它可能不会太重要,如果确实如此,那将是因为解码函数,这在问题中没有给出。

理论上你有两种交易情况,它将决定(1)或(2)是否更快。

假设解码速度很快,因此您的进程将受IO限制。

如果通过将整个文件一次性读入内存,您进行较少的上下文切换,那么您将在这些上下文切换上浪费较少的CPU周期,因此读取整个文件的速度会更快。

如果通过char读取char文件,你不会过早地花时间到CPU那么理论上你可以使用IO等待CPU周期来运行 解码所以然后char的char更快。

以下是一些时间表

通过char good case

读取char
TIME    -------------------------------------------->
IO:     READ CHAR --> wait -->   READ CHAR --> wait 
DECODE: wait ------> DECODE --> wait --->  DECODE ...

通过char bad case

读取char
TIME    -------------------------------------------->
IO:     READ CHAR --> YIELD          -->  READ CHAR --> wait 
DECODE: wait ------>  YIELD          --> DECODE --->  wait DECODE ---> ...

读取整个文件

TIME    -------------------------------------------->
IO:     READ CHAR .....  READ CHAR --> FINISH
DECODE: -----------------------------> DECODE --->

如果您的解码非常慢,那么生产者消费者模型可能会更快。最好的办法是使用BufferedReader尽可能多地执行IO,同时减少/产生最少的CPU周期。

答案 1 :(得分:3)

使用BufferedReader或BufferedInputStream然后逐字符处理是没问题的;缓冲区将一次透明地读取多个字符。这应该足以满足典型要求。

读取整个字符串称为" slurping"并且给定的内存开销通常被认为是文件处理的最后手段。如果你正在逐个字符地处理内存中的字符串,它甚至可能没有可检测的速度优势,因为你所做的只是你自己的(非常大的)缓冲区。

使用BufferedReader或BufferedInputStream,您可以调整缓冲区大小,以便在必要时可以很大。

鉴于您的文件大小(20-30mb),根据该文件的编码,请注意Java char是16位,因此对于ASCII文本文件或具有少量扩展字符的UTF-8文件,您必须允许将典型JVM实现的内存使用量增加一倍。

答案 2 :(得分:0)

这取决于解码处理。

如果可以并行化,则可以考虑使用map / reduce方法。将文件内容分解为单独的映射步骤,并将它们组合在一起以在reduce步骤中获得最终结果。

大多数机器都有多个核心。如果处理器之间不需要通信,如果您有N个内核,则可以将处理时间减少1 / N.如果你有可以利用的GPU,你真的会有所收获。