10

63000 行 (3.5 MB) の長さのテキスト ファイル (XStream で作成された XML) があります。バッファリーダーを使用して読み取ろうとしています:

                BufferedReader br = new BufferedReader(new FileReader(file));
                try {
                    String s = "";
                    String tempString;
                    int i = 0;
                    while ((tempString = br.readLine()) != null) {
                        s = s.concat(tempString);
//                        s=s+tempString;
                        i = i + 1;
                        if (i % 1000 == 0) {
                            System.out.println(Integer.toString(i));
                        }
                    }
                    br.close();

ここでは、読書速度を測定するための私の試みを見ることができます。そして、それは非常に低いです。10000 行から 1000 行を読み取るのに数秒かかります。私は明らかに何か間違ったことをしていますが、何が理解できません。よろしくお願いします。

4

4 に答える 4

4

@PaulGrimeは正しいです。ループが行を読み取るたびに文字列をコピーしています。文字列が大きくなると (たとえば 10,000 行になると)、そのコピーを行うために多くの作業が行われます。

これを試して:

StringBuilder sb = new StringBuilder();
while (...reading lines..){ 
   ....
   sb.append(tempString);  //should add newline
   ...
}

s = sb.toString();

注:改行を削除するとファイルを読み取るのが悪い方法になる理由については、以下のPaulの回答を読んでください。また、質問のコメントで述べたように、XStream はファイルを読み取る方法を提供します。そうでない場合でも、 IOUtils.toString(reader) はファイルを読み取るより安全な方法です。

于 2013-04-06T10:33:52.400 に答える
4

あなたができるいくつかの即時の改善:

  • andの代わりにStringBuilderを使用します。andを使用すると、特にループで使用する場合に、パフォーマンスに大きな影響を与える可能性があります。concat++concat
  • ディスクへのアクセスを減らします。大きなバッファを使用してそれを行うことができます:

    BufferedReader br = new BufferedReader(new FileReader("someFile.txt"), SIZE);

于 2013-04-06T10:34:04.183 に答える
3

連結は小さな文字列でも非常に遅いため、StringBuilderを使用する必要があります。String

さらに、 ではなく NIO を使用してみてくださいBufferedReader

public static void main(String[] args) throws IOException {
    final File file = //some file
    try (final FileChannel fileChannel = new RandomAccessFile(file, "r").getChannel()) {
        final StringBuilder stringBuilder = new StringBuilder();
        final ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        final CharsetDecoder charsetDecoder = Charset.forName("UTF-8").newDecoder();
        while (fileChannel.read(byteBuffer) > 0) {
            byteBuffer.flip();
            stringBuilder.append(charsetDecoder.decode(byteBuffer));
            byteBuffer.clear();
        }
    }
}

それでも遅すぎる場合は、バッファ サイズを調整できます。どのバッファ サイズが適切に機能するかは、システムに大きく依存します。私にとっては、バッファーが 1K であろうと 4K であろうとほとんど違いはありませんが、他のシステムでは速度が 1 桁向上することを知っています。

于 2013-04-06T10:40:30.337 に答える