約2000文字の文字列バッファーがあり、特定の文字列が含まれているかどうかを確認する必要があります。
すべてのwebrequestに対してASP.NET 2.0 webappでチェックを行います。
String.Containsメソッド のパフォーマンスが String.IndexOfメソッド よりも優れているかどうかは誰にもわかりますか?
// 2000 characters in s1, search token in s2
string s1 = "Many characters. The quick brown fox jumps over the lazy dog";
string s2 = "fox";
bool b;
b = s1.Contains(s2);
int i;
i = s1.IndexOf(s2);
Contains
はIndexOf
を呼び出します:
_public bool Contains(string value)
{
return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
}
_
最終的にCLR実装を使用する_CompareInfo.IndexOf
_を呼び出します。
CLRで文字列がどのように比較されるかを確認したい場合 これにより表示されます (CaseInsensitiveCompHelperを探します)。
IndexOf(string)
にはオプションがなく、Contains()
は順序比較を使用します(eとéなどのスマート比較を実行するのではなく、バイトごとの比較)。
したがって、IndexOf
はkernel32.dllのFindNLSStringを使用した文字列検索(リフレクターの力!)に直接進むため、IndexOf
は(理論上)わずかに高速になります。
。NET 4.0用に更新-IndexOfは順序比較を使用しなくなったため、Containsはより高速になりました。以下のコメントを参照してください。
おそらく、それはまったく問題ではないでしょう。 Coding Horrorに関するこの投稿を読んでください;): http://www.codinghorror.com/blog/archives/001218.html
Contains(s2)は、IndexOf(s2)よりも何倍も(私のコンピューターでは10倍)高速です http://davesbox.com/archive/2008/11/12/breaking-changes-to-the-string-class.aspx )。
Containsは、テストではIndexOf(s2、StringComparison.Ordinal)> = 0とまったく同じパフォーマンスを持ちますが、より短く、意図が明確になります。
私は実際のケースを実行しています(合成ベンチマークとは反対に)
if("=,<=,=>,<>,<,>,!=,==,".IndexOf(tmps)>=0) {
versus
if("=,<=,=>,<>,<,>,!=,==,".Contains(tmps)) {
これは私のシステムの重要な部分であり、131,953回実行されます(DotTraceに感謝します)。
しかし、衝撃的な驚き、結果は予想とは反対です
:-/
ネットフレームワーク4.0(2012年2月13日更新)
Reflectorを使用すると、ContainsがIndexOfを使用して実装されていることがわかります。これが実装です。
public bool Contains(string value)
{
return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
}
したがって、ContainsはIndexOfを直接呼び出すよりも少し遅い可能性がありますが、実際のパフォーマンスに重要な意味があるとは思いません。
コードを本当に最適化したい場合、最良のアプローチは常にベンチマークです。
.netフレームワークには優れたストップウォッチ実装があります- System.Diagnostics.Stopwatch
少し読んでみると、内部ではString.Containsメソッドが単にString.IndexOfを呼び出しているように見えます。違いは、String.Containsはブール値を返しますが、String.IndexOfは、部分文字列が見つからなかったことを表す(-1)の整数を返します。
100,000程度の反復で小さなテストを書くことをお勧めします。推測するなら、IndexOfの方が少し速いかもしれませんが、先ほど言ったように推測にすぎません。
Jeff Atwoodが his blog で文字列に関する優れた記事を公開しています。連結についての詳細ですが、それでも役に立つかもしれません。
これの更新として、テストを行い、入力文字列がかなり大きい場合、並列Regexが私が見つけた最速のC#メソッドです(複数のコアがある場合)
たとえば、一致の合計量を取得する-
needles.AsParallel ( ).Sum ( l => Regex.IsMatch ( haystack , Regex.Escape ( l ) ) ? 1 : 0 );
お役に立てれば!
Jon Skeetからのこの最近の進出 のようなベンチマークライブラリを使用して、それを測定します。
すべての(マイクロ)パフォーマンスの質問と同様に、これは使用しているソフトウェアのバージョン、検査されたデータの詳細、および呼び出しを取り巻くコードによって異なります。
すべての(マイクロ)パフォーマンスの質問と同様に、最初のステップは、簡単に保守可能な実行バージョンを取得することです。その後、推測する代わりに、ベンチマーク、プロファイリング、チューニングを測定されたボトルネックに適用できます。