我在文件中有一个大字符串(它的编码数据,我的自定义编码),我想读它并将其处理成我的特殊格式(解码)。我想知道我能以最快的方式获得最终格式。我想到了一些方法,但不确定哪种方式最好。
1)读取1行中的整个字符串,然后处理该字符串。
2)在阅读时,从文件和进程中逐个字符读取。
有人可以帮忙吗? 感谢
答案 0 :(得分:4)
进程可能是IO绑定而不是CPU绑定所以它可能不会太重要,如果确实如此,那将是因为解码函数,这在问题中没有给出。
理论上你有两种交易情况,它将决定(1)或(2)是否更快。
假设解码速度很快,因此您的进程将受IO限制。
如果通过将整个文件一次性读入内存,您进行较少的上下文切换,那么您将在这些上下文切换上浪费较少的CPU周期,因此读取整个文件的速度会更快。
如果通过char读取char文件,你不会过早地花时间到CPU那么理论上你可以使用IO等待CPU周期来运行 解码所以然后char的char更快。
TIME -------------------------------------------->
IO: READ CHAR --> wait --> READ CHAR --> wait
DECODE: wait ------> DECODE --> wait ---> DECODE ...
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,你真的会有所收获。