2012年7月27日 星期五

最佳化 Java File I/O

[1] 這篇文章是研究怎樣讀取檔案最快的開箱文 (?!)
一開始先說明了 Java 常用的 14 種讀取檔案的方法,並簡單說明主要的優點(例如有沒有 thread-safety)
然後開始做各種方法的效率測試。

以下幾張圖轉錄自該篇文章:


Full plot


Zoomed plot


Really zoomed plot


Comparison to C

較詳細的說明請直接參閱 [1] 的原文。
而測試後的原文結論如下:
For the best Java read performance, there are four things to remember:
  • Minimize I/O operations by reading an array at a time, not a byte at a time. An 8Kbyte array is a good size.
  • Minimize method calls by getting data an array at a time, not a byte at a time. Use array indexing to get at bytes in the array.
  • Minimize thread synchronization locks if you don't need thread safety. Either make fewer method calls to a thread-safe class, or use a non-thread-safe class like FileChannel and MappedByteBuffer.
  • Minimize data copying between the JVM/OS, internal buffers, and application arrays. Use FileChannel with memory mapping, or a direct or wrapped array ByteBuffer.

2013/01/10 補充:
根據 [3] 的討論,使用 NIO 主要快的原因應該在於 NIO 可以呼叫 OS 的 DMA
直接磁碟對磁碟地進行傳輸,效率就會比較高。
不過我自己實際測試時,用傳統的 FileOutputStream 效率卻遠高於使用 FileChannel
也許是因為我現在測試的電腦只有一顆硬碟的關係?
亦即有可能是同顆硬碟的 File I/O,用傳統方法比較快;跨硬碟的 File I/O 則是用 NIO 比較快??
(這是未經實驗測試的臆測~)

參考資料:
1、Java tip: How to read files quickly
2、Tweak your IO performance for faster runtime
3、Java NIO FileChannel versus FileOutputstream performance / usefulness
4、Using FileChannel instead of RandomAccessFile

沒有留言: