45

7000万行のテキストを含む大きなテストファイルがあります。ファイルを1行ずつ読み取る必要があります。

私は2つの異なるアプローチを使用しました:

InputStreamReader isr = new InputStreamReader(new FileInputStream(FilePath),"unicode");
BufferedReader br = new BufferedReader(isr);
while((cur=br.readLine()) != null);

LineIterator it = FileUtils.lineIterator(new File(FilePath), "unicode");
while(it.hasNext()) cur=it.nextLine();

このタスクを高速化できる別のアプローチはありますか?

4

7 に答える 7

50

1)速度に違いはないと確信しています。どちらも FileInputStream を内部で使用し、バッファリングを使用します

2)測定して自分の目で確かめることができます

3) パフォーマンス上の利点はありませんが、1.7 のアプローチが気に入っています

try (BufferedReader br = Files.newBufferedReader(Paths.get("test.txt"), StandardCharsets.UTF_8)) {
    for (String line = null; (line = br.readLine()) != null;) {
        //
    }
}

4) スキャナーベースのバージョン

    try (Scanner sc = new Scanner(new File("test.txt"), "UTF-8")) {
        while (sc.hasNextLine()) {
            String line = sc.nextLine();
        }
        // note that Scanner suppresses exceptions
        if (sc.ioException() != null) {
            throw sc.ioException();
        }
    }

5) これは残りより速いかもしれません

try (SeekableByteChannel ch = Files.newByteChannel(Paths.get("test.txt"))) {
    ByteBuffer bb = ByteBuffer.allocateDirect(1000);
    for(;;) {
        StringBuilder line = new StringBuilder();
        int n = ch.read(bb);
        // add chars to line
        // ...
    }
}

少しコーディングが必要ですが、ByteBuffer.allocateDirect. ByteBufferこれにより、OS はバイトをコピーせずにファイルから直接読み取ることができます。

6) 並列処理は間違いなく速度を向上させます。大きなバイトバッファを作成し、ファイルからそのバッファにバイトを並行して読み取るいくつかのタスクを実行し、準備ができたら最初の行末を見つけ、を作成しString、次を検索...

于 2012-12-26T07:40:34.680 に答える
11

あなたがパフォーマンスを見ているなら、あなたはjava.nio.*パッケージを見ることができます-それらはおそらくより速いですjava.io.*

于 2012-12-26T07:33:56.980 に答える
1

この記事は、始めるのに最適な方法です。

また、最初の 10,000 行 (またはそれ以外ですが、小さすぎてはいけません) を読み取るテスト ケースを作成し、それに応じて読み取り時間を計算する必要があります。

スレッド化は良い方法かもしれませんが、データで何をするかを知っておくことが重要です。

考慮すべきもう 1 つのことは、そのサイズのデータ​​をどのように格納するかです。

于 2012-12-26T07:42:58.720 に答える
1

次の 3 つの方法を試しました。ファイル サイズは 1M で、結果が得られました。

ここに画像の説明を入力

プログラムを数回実行すると、BufferedReader の方が速いようです。

@Test
public void testLargeFileIO_Scanner() throws Exception {

    long start = new Date().getTime();

    String fileName = "/Downloads/SampleTextFile_1000kb.txt"; //this path is on my local
    InputStream inputStream = new FileInputStream(fileName);

    try (Scanner fileScanner = new Scanner(inputStream, StandardCharsets.UTF_8.name())) {
        while (fileScanner.hasNextLine()) {
            String line = fileScanner.nextLine();
            //System.out.println(line);
        }
    }
    long end = new Date().getTime();

    long time = end - start;
    System.out.println("Scanner Time Consumed => " + time);

}


@Test
 public void testLargeFileIO_BufferedReader() throws Exception {

    long start = new Date().getTime();

    String fileName = "/Downloads/SampleTextFile_1000kb.txt"; //this path is on my local
    try (BufferedReader fileBufferReader = new BufferedReader(new FileReader(fileName))) {
        String fileLineContent;
        while ((fileLineContent = fileBufferReader.readLine()) != null) {
            //System.out.println(fileLineContent);
        }
    }
    long end = new Date().getTime();

    long time = (long) (end - start);
    System.out.println("BufferedReader Time Consumed => " + time);

}


@Test
public void testLargeFileIO_Stream() throws Exception {

    long start = new Date().getTime();

    String fileName = "/Downloads/SampleTextFile_1000kb.txt"; //this path is on my local
    try (Stream inputStream = Files.lines(Paths.get(fileName), StandardCharsets.UTF_8)) {
        //inputStream.forEach(System.out::println);
    }
    long end = new Date().getTime();

    long time = end - start;
    System.out.println("Stream Time Consumed => " + time);

}
于 2019-02-12T08:57:59.347 に答える