2009-04-10 24 views
10

私は現在、'~'で区切られた文字列の数を持つファイルをスキャンするのにsplit()を使用しています。私はどこかでScannerが長いファイル、パフォーマンス面でより良い仕事をすることができると読んだので、私はそれをチェックアウトすることを考えました。Javaのスキャナvs String.split()vs StringTokenizer;それは私が使うべきですか?

私の質問は:Scannerという2つのインスタンスを作成する必要がありますか?つまり、行を読み込む行と、行に基づいて行を読み取って区切り記号のトークンを取得する行頭?もし私がそうする必要があれば、私はそれを使うことから何らかの利点が得られるのかどうか疑問に思う。多分私はここに何かを見逃していますか?

答えて

3

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

編集:両方の実装を常にテストして、どちらが高速かを確認することができます。 scannersplit()よりも速くなる可能性がある場合、私は自分自身が好奇心が強いです。所与のサイズVS Scannerの方がスプリットスピードが速いかもしれませんが、それは確信できません。

+0

私は、StringTokenizerは廃止される可能性があることに同意しますが、j2se5とjava6の廃止予定クラスのリストでそれを見つけられませんでした。どうして? – gedevan

+0

StringTokenzierは非推奨ではありません... – Jon

+0

あなたはそうです、そうではありません。しかしAPIから: StringTokenizerは互換性のために保持されているレガシークラスですが、新しいコードでの使用は推奨されません。この機能を求めている人は、Stringのsplitメソッドまたはjava.util.regexパッケージを代わりに使用することをお勧めします。 – CookieOfFortune

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(); 
} 
5

あなたはまだライン自身を反復処理するhasNextLine()/nextLine()を使用しているときに、hasNext()/next()と各ライン上のトークンを反復処理できるようにuseDelimiter("~")メソッドを使用することができます。

EDIT:あなたは性能比較をやろうとしている場合は、分割を行うとき、あなたは正規表現をプリコンパイルする必要があります()テスト:あなたはString#split(String regex)を使用している場合

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

、正規表現が再コンパイルされます毎回。 (スキャナーは最初にコンパイルしたときにすべての正規表現を自動的にキャッシュします)。そうすることで、パフォーマンスに大きな違いは見込まれません。

2

固定文字列で分割しているので、実際には正規表現は必要ありません。 Apache StringUtilssplitプレーンストリングで分割しません。

分割がボトルネックの場合、ファイルIOというよりも、ボリュームが大きい場合、これは最大でもString.split()の10倍の速さです。しかし、私はコンパイルされた正規表現に対してテストしませんでした。

グアバにはさらに多くの方法で実装されたスプリッタがありますが、ボリューム分割のためにStringUtilsよりもかなり遅いことがわかりました。

8

シングルスレッドモデルでこれらを取り巻くメトリックはいくつかありましたが、ここで得られた結果があります。

 
~~~~~~~~~~~~~~~~~~Time Metrics~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
~ Tokenizer | String.Split() | while+SubString | Scanner | ScannerWithCompiledPattern ~ 
~ 4.0 ms |  5.1 ms  |  1.2 ms  |  0.5 ms |    0.1 ms   ~ 
~ 4.4 ms |  4.8 ms  |  1.1 ms  |  0.1 ms |    0.1 ms   ~ 
~ 3.5 ms |  4.7 ms  |  1.2 ms  |  0.1 ms |    0.1 ms   ~ 
~ 3.5 ms |  4.7 ms  |  1.1 ms  |  0.1 ms |    0.1 ms   ~ 
~ 3.5 ms |  4.7 ms  |  1.1 ms  |  0.1 ms |    0.1 ms   ~ 
____________________________________________________________________________________________________________ 

出てくるが、スキャナが最高のパフォーマンスを与えることをマルチスレッド・モードで評価されるようになりました同じニーズです!私のシニアの一人は、TokenizerはCPUスパイクを与え、String.splitはそうではないと言います。

関連する問題