簡體   English   中英

為什么這個“行數”程序在Java中變慢? 使用MappedByteBuffer

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM