1

NIO (単一ファイルの読み取りが最も遅い)、BufferedInputStream を使用してファイルを文字列に読み取るいくつかのアプローチのパフォーマンスを測定しようとしました。バッファとして機能する固定サイズ (最速)

ファイルは、Windows .txt ファイル形式の 95 MB の純粋なテキストでした。文字を文字列に変換することは実際にはボトルネックですが、私が気づいたのは、このメソッドの膨大なメモリ消費です。95 MB の lorem ipsum の場合、これは最大 1 GB の RAM を消費します。理由はわかりません。

私が効果なしで試したこと:

System.gc() を呼び出してガベージ コレクターを発行する メソッドが終了する前に、すべてのポインター変数を null に設定します (ただし、メソッド内でのみ定義されている必要があります)。

private void testCharStream() {
            File f = f = new File("c:/Downloads/test.txt");
    long oldTime = System.currentTimeMillis();
    char[] cbuf = new char[8192];
    StringBuilder builder = new StringBuilder();
    try {

        FileReader reader = new FileReader(f);

        while (reader.read(cbuf) != -1) {
            builder.append(cbuf);
        }

        reader.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    long currentTime = System.currentTimeMillis();

    System.out.println(currentTime - oldTime);
}
4

3 に答える 3

0

私はまともな解決策を思いつきました。Apache Commons IO パッケージを使用した場合、メモリのピークは777.1 MBで、最低は 220 MB で、95 MB のテキスト ファイルが赤色になるために必要な平均は 710 ミリ秒でした。

私がしたことは、メソッドの最後で StringBuilder オブジェクトへのポインターを持つ変数を null に設定し、ガベージ コレクターが実際にその作業を行うことを提案することでした (System.gc())。メモリのピーク時は540 MBで、以前に達成された値の 1/2 以上です。また、バッファー サイズを 1024 に変更すると、パスごとに 40 ミリ秒 (490 から 450 またはそれ以下) の改善が得られます。したがって、私の関数は、ファイルを読み取るために Apache の時間の63.4%しか必要としません。それはほぼ40%少ないです。パフォーマンスをさらに向上させる方法はありますか?

これが関数です。

private void testCharStream() {
    long oldTime = System.currentTimeMillis();
    char[] cbuf = new char[1024];
    StringBuilder builder = new StringBuilder();

    try {

        FileReader reader = new FileReader(f);

        while (reader.read(cbuf) != -1) {
            builder.append(cbuf);
        }

        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    long currentTime = System.currentTimeMillis();
    builder = null;
    System.gc();
    System.out.println(currentTime - oldTime);
}
于 2013-08-25T14:58:45.453 に答える