2011-11-25 2 views
5


私は最適化したいコードでこれを見つけました。ここ はsnipetです:これは通常のJava正規表現の動作ですか?

tempString = bigBuffer.replaceAll("\\n", ""); 
tempString = tempString.replaceAll("\\t", ""); 

は、その後、私は賢明に正規表現を使用することを決めたと、私はこれをしなかった:

tempString = bigBuffer.replaceAll("[\\n\\t]", ""); 

その後、友人が代わりにこれを行うために私に言った:

tempString = bigBuffer.replaceAll("\\n|\\t", ""); 

私は自分の変更の結果を知りたいので、私はそれが良い最適化であるかどうかを検証するためのテストを行いました。したがって、(Javaバージョン "1.6.0_27")の結果は、最初のコードが参照100%であることになります。

パイプでは121%なので、タスクを実行するのに時間がかかりました。

角括弧では52%なので、タスクを実行するのに時間がかかりませんでした。

なぜ正規表現は同じでなければならない場所が違うのですか?

マーティン

+0

なぜ同じにする必要がありますか? – BoltClock

+0

同じことをするので、同じでなければならないと私は信じています。パイプが単一文字で使用される場合、コンパイラは最適化を必要とするかもしれません。 – Martin

答えて

4

は、最初のコードスニペットは、新しい行を置き換える、二回bigBufferを介して第1の時間を見て、二回目は、タブを置き換えます。

2番目のコードスニペットは、bigBufferを1回だけ検索し、各文字がどちらか一方であるかどうかを確認します。これにより、半分の時間でスピードが終わることになります。

3番目のコードスニペットはおそらくコンパイルされていないため、最初のコードのアルゴリズムは特に悪いバージョンになります。ただし、正規表現のコンパイル時のパスを慎重に調べることはできません。

しかし、テストで優れた作業。相対タイミング(パーセントベース)は有用であり、絶対タイミング(ミリ秒など)はそうではありません。

2

一般的に言えば、文字クラス([abc])は同等の代替(a|b|c)よりも効率的な傾向があります。なぜなら、あなたの友人がそれを示唆する理由はわかりません。しかし、Javaでは、Latin1レパートリーの文字(すなわち最初の256個のUnicodeコードポイント)と一致する文字クラスがさらに最適化されます。それは、おそらく、第2の技術と第3の技術の大きな違いがある理由です。

また、これはJavaだけです。 Perlでは、私は交替と文字クラスの違いが無視できると思っています。これははるかに成熟した実装です。そして、grepでは、あなたが使った3つのアプローチのうちのどれを使用しているかにかかわらず、違いを測定するのはおそらく困難です。

しかし、経験則として、文字クラスまたは代替文字を使用するかどうかを選択する場合は、文字クラスを優先する必要があります。それは速くないかもしれませんが、間違いなく遅くなることはありません。そして不適切に使用されると、交替はパフォーマンスに悲惨な影響を与える可能性があります。

+0

親指のおかげで、私は友人がそれについて知っていることを確認します。 – Martin

関連する問題