[英]Why is this “line count” program slow in Java? Using MappedByteBuffer
為了嘗試使用MappedByteBuffer
(Java中的內存映射文件),我編寫了一個簡單的wc -l
(文本文件行計數)演示:
int wordCount(String fileName) throws IOException {
FileChannel fc = new RandomAccessFile(new File(fileName), "r").getChannel();
MappedByteBuffer mem = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
int nlines = 0;
byte newline = '\n';
for(long i = 0; i < fc.size(); i++) {
if(mem.get() == newline)
nlines += 1;
}
return nlines;
}
我在大約15 MB(15008641字節)和100k行的文件上嘗試了這個。 在我的筆記本電腦上,大約需要13.8 sec
。 為什么這么慢?
完整的類代碼在這里: http : //pastebin.com/t8PLRGMa
作為參考,我在C中寫了相同的想法: http : //pastebin.com/hXnDvZm6
它運行大約28毫秒,或490 times faster
。
出於好奇,我還使用與Java中基本相同的算法和API編寫了Scala版本。 它的運行10 times faster
,這表明肯定存在一些奇怪的現象。
更新 :該文件由操作系統緩存,因此不會涉及磁盤加載時間。
我想使用內存映射來隨機訪問可能不適合RAM的較大文件。 這就是為什么我不只是使用BufferedReader。
代碼非常慢,因為在循環中調用fc.size()
。
JVM顯然無法消除fc.size()
,因為文件大小可以在運行時更改。 查詢文件大小相對較慢,因為它需要對底層文件系統進行系統調用。
將此更改為
long size = fc.size();
for (long i = 0; i < size; i++) {
...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.