java中多種寫文件方式的效率對比實驗


實驗背景

最近在考慮一個問題:“如果快速地向文件中寫入數據”,java提供了多種文件寫入的方式,效率上各有異同,基本上可以分為如下三大類:字節流輸出、字符流輸出、內存文件映射輸出。前兩種又可以分為帶buffer及不帶buffer。

實驗目標

通過實驗找出單線程場景下文件寫入效率最高的方式,並量化各種文件寫入方式在效率上的差距。

實驗設計

為減少其他環節的影響,示例代碼使用循環輸出同一字符串多次的方式測試整個輸出環節的耗時,通過耗時、服務器資源使用情況(cpu、內存使用)等指標評判各種文件寫入方式的效率好壞。

實驗環境

OS: windows 7 64bit

cpu: 4core, 主頻:2.4GHZ

mem:6G

jdk version:Java HotSpot(TM) 64-Bit ,1.8.0_101

實驗步驟

總共進行8次輸出實驗,依次輸出的文件大小為:10M、50M、100M、200M、500M、800M、1G、2G;

每次輸出后記錄各種方式的耗時情況,並填表。

實驗結果

表1、java各種文件寫入方法效率對比實驗時延數據表

 

表1、java各種文件寫入方法效率對比實驗時延結果圖(含大文件)

 

 表2、java各種文件寫入方法效率對比實驗時延結果圖(不含大文件)

  

 

圖2、文件大小為2048m時,各個寫入方式執行任務時cpu使用情況:

圖3、文件大小為2048m時,各個寫入方式執行任務時jvm內存使用情況

圖4、文件大小為2048m時,各個寫入方式執行任務時物理內存使用情況:

上圖中紅圈中為‘FileChannel’方式下的物理內存使用情況。

實驗結論

1、基本上,五種寫入方式的時延從小到大排序為:FileChannel<BufferedOutputStream<FileOutputStream<BufferedWriter<FileWriter;從表1、圖1;可以看出;且該規律在小文件寫入的情景下,更為明顯,圖2可以看出;

2、在同樣文件大小寫入的場景中,通常意義上帶buffer的字節流輸入/字符流輸入比不帶buffer的對應流效率要高;

3、各個寫入方式的jvm cpu和內存使用情況大致相當,從圖2和圖3可以看出;

4、文件達到一定大小后( fileSize >=1.5G ),FileChannel的時延變得很大且不穩定,從圖1最右邊可以看出;同時,物理內存的使用量基本和寫入文件大小相當,從圖4可以看出;原因在於FileChannel使用MappedByteBuffer寫入,這個buffer是direct buffer,直接操作物理內存寫入,故而造成物理內存消耗嚴重。

5、小文件寫入的場景下(1M左右),FileChannel有些大材小用了,效率上反而沒有字節流效率高。

綜上,我們可以得到幾條有價值的使用經驗:

1、小文件(幾M的文件)寫入時,使用常規的io輸入就行,最優選擇是BufferedInportStream,沒有必要使用nio的FileChannel;

2、大文件(fileSize > 1G,這是個經驗值,需要根據具體環境具體分析)寫入時,使用FileChannel需要小心物理內存的瓶頸帶來的寫入效率低下,可以考慮使用分段寫入的方式(TODO:后續實驗給出);

3、其他場景下,如果效率優先的考慮,則優先選擇FileChannel寫入文件。

demo

參考git倉庫:https://github.com/daoqidelv/io-demo 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM