[英]Best way to read huge file in MB in java
我正在閱讀帖子,它說使用BufferedReader或MappedByteBuffer。 我決定用291.0 MB文件自己測試,但仍然無法決定
BufferedReader reader = new BufferedReader(new FileReader("/Users/rachana/part-00000"));
String line = null;
while((line = reader.readLine())!=null) {
System.out.println(line);
}
~~~~~~ Heap utilization in MB ~~~~~~
Start Date 21:10:20
End Date 21:17:48
Time used 448 second
7.50 min
Used Memory In MB:28
Free Memory:81
Total Memory:109
Max Memory:1820
使用MappedByteBuffer
RandomAccessFile aFile = new RandomAccessFile
("/Users/rachana/part-00000", "r");
FileChannel inChannel = aFile.getChannel();
MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
buffer.load();
for (int i = 0; i < buffer.limit(); i++)
{
System.out.print((char) buffer.get());
}
buffer.clear(); // do something with the data and clear/compact it.
inChannel.close();
aFile.close();
~~~~~~ Heap utilization in MB ~~~~~~
Start Date 21:20:40
End Date 21:33:52
Time used 792 sec / 13.2 min
Used Memory In MB:4
Free Memory:104
Total Memory:109
Max Memory:1820
它清楚地表明MappedByteBuffer使用更少的內存,但更多的時間,因為BufferedReader使用更多的內存但更少的時間。
我試圖找到平衡也使用MappedByteBuffer讀取行。
任何建議都會有所幫助
你正在做的最慢的部分是打印到屏幕上。 我建議你不要這樣做,你會很好的MemoryMapped文件更快(如果你不是一次打印一個字符到控制台)
注意:除非您使用的是IS-8859-1或US-ASCII編碼的文本文件,否則這兩個不可互換。 BufferedReader用於文本和內存映射文件用於二進制。
順便說一下如果忽略你執行的GC的數量,沒有必要查看使用的內存。 如果你只關心在開始和結束時使用的內存,你應該在測量之前用System.gc()做一個完整的GC,我希望在這兩種情況下你會看到一個小的,隨機的差異(可能是負面的)。
如果您關於分配的情況,您需要更大的伊甸園大小,例如2 GB,它開始為空(在完整GC之后),或者您可以使用分析器來測量分配。 在第一種情況下,字符串將分配最多的數據,在第二種情況下,寫入控制台將創建最多。
它清楚地表明MappedByteBuffer使用更少的內存,但更多的時間,因為BufferedReader使用更多的內存但更少的時間。
顯然,這不可能是真的,事實並非如此。 您使用MappedByteBuffer將整個300MB文件映射到內存中MappedByteBuffer,
而不是使用BufferedReader
。 解釋是MappedByteBuffer
內存不是來自堆。 它使用內存,與文件大小一樣多,這遠遠超過了你的BufferedReader
代碼。 你不是在這里測量它。
類似地,您的時間測量也是無效的,因為它們由System.out.println()控制,它不是輸入,並且希望哪個也不是最終應用程序的一部分。
因此,您的基准測試在所有方面都完全無效。
使用BufferedReader
。 你可以每秒讀取數百萬行。 它足夠快。
我會選擇第一個,除非你真的試圖刮掉桶以進行內存優化。
原因:
在進行文件I / O時,您應該記住,I / O操作可能比代碼中的CPU所做的任何工作都要慢得多。
但還有其他一些考慮因素。 優化往往會使代碼更復雜,更難理解。 要理解MappedByteBuffer
代碼,讀者需要了解MappedByteBuffer
如何工作以及他們需要理解文件輸入的所有內容。
文件閱讀通常是完成的。 因此,Java已經提供了幫助您的代碼,這一點不應該讓您感到驚訝。 該代碼將由專家編寫,經過測試和調試。 除非您有特殊要求,否則應始終使用此類代碼而不是自己編寫代碼。 也就是說,我建議使用BufferedReader
(您的第一種方法)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.