10

現在split()、各行に で区切られた文字列の数があるファイルをスキャンするために使用しています'~'Scannerパフォーマンスの観点から、長いファイルでより良い仕事をすることができるどこかを読んだので、それをチェックアウトすることを考えました.

私の質問は: の 2 つのインスタンスを作成する必要がありScannerますか? つまり、1 つは行を読み取り、もう 1 つはその行に基づいて区切り文字のトークンを取得しますか? そうしなければならない場合、それを使用することで何か利点があるかどうかは疑問です。多分私はここで何かを逃していますか?

4

5 に答える 5

6

行の処理にはスキャナーを使用でき、各行からのトークンの取得には分割を使用できます。

Scanner scanner = new Scanner(new File(loc));
try {
    while ( scanner.hasNextLine() ){
        String[] tokens = scanner.nextLine().split("~");
        // do the processing for tokens here
    }
}
finally {
    scanner.close();
}
于 2009-04-10T04:07:23.877 に答える
5

このuseDelimiter("~")メソッドを使用して、 を使用して各行のトークンを繰り返し処理しhasNext()/next()ながらhasNextLine()/nextLine()、行自体を繰り返し処理することができます。

編集: パフォーマンスの比較を行う場合は、split() テストを行うときに正規表現をプリコンパイルする必要があります。

Pattern splitRegex = Pattern.compile("~");
while ((line = bufferedReader.readLine()) != null)
{
  String[] tokens = splitRegex.split(line);
  // etc.
}

を使用するString#split(String regex)と、正規表現は毎回再コンパイルされます。(Scanner は、最初に正規表現をコンパイルするときに、すべての正規表現を自動的にキャッシュします。) そうすれば、パフォーマンスに大きな違いは見られないと思います。

于 2009-04-10T04:19:19.557 に答える
3

split()は最速であり、おそらくあなたがしていることには十分だと思います。それよりscannerも柔軟性がありません。StringTokenizerは推奨されておらず、下位互換性のためにのみ使用できるため、使用しないでください。

編集: 両方の実装をいつでもテストして、どちらが高速かを確認できます。scannerよりも速くなるかどうか、私は自分自身に興味がありますsplit()。Split は、特定のサイズの VS の方が高速である可能性がありますがScanner、それについては確信が持てません。

于 2009-04-10T04:00:31.270 に答える
2

固定文字列で分割しているため、ここでは実際には正規表現は必要ありません。ApacheStringUtils 分割は、プレーンな文字列で分割を行います。

ファイル IO ではなく、分割がボトルネックとなる大量の分割の場合、これは .NET よりも最大 10 倍高速であることがわかりましたString.split()。ただし、コンパイルされた正規表現に対してはテストしませんでした。

Guava にはスプリッターもあり、よりオブジェクト指向の方法で実装されていますが、大容量の分割では StringUtils よりも大幅に遅いことがわかりました。

于 2012-07-13T06:01:36.783 に答える