String.Contains方法は、ここで別のコールは、関連するCompareInfo.IndexOf
メソッドを呼び出して、最終的な過負荷に行われるこのString.Containsが最後のオーバーロードを直接呼び出すのはなぜですか?
public int IndexOf(string value, StringComparison comparisonType)
{
return this.IndexOf(value, 0, this.Length, comparisonType);
}
のようなルックスと呼ばれ、この内部
public bool Contains(string value)
{
return this.IndexOf(value, StringComparison.Ordinal) >= 0;
}
IndexOf
過負荷のように見えます署名付き
public int IndexOf(string value, int startIndex, int count, StringComparison comparisonType)
したがって、最終的な過負荷は最も速くなります(ほとんどの場合、マイクロ最適化と見なすこともできます)。 メソッドは、中間コールで他の作業が行われていないことと、同じ情報が両方のステージで利用可能であることを考慮して、最終的なオーバーロードを直接呼び出さないのはなぜですか?
最終的なオーバーロードのシグネチャが変更された場合、変更が1回だけ(中間方法のもの)必要であるか、それ以上にデザインが増えるという唯一の利点はありますか?私はどこかでミスを犯してきた場合には取得していますパフォーマンスの違いを明確にコメントから
編集(速度差の説明のための2を更新参照)
: は、私は(this benchmarkを走ったが5回ループジッタバイアスを回避するため)、ループはこの
0123のように見えるとString.Contains
方法
public static bool QuickContains(this string input, string value)
{
return input.IndexOf(value, 0, input.Length, StringComparison.OrdinalIgnoreCase) >= 0;
}
と比較するために、この拡張メソッドを使用
ベンチマークテストでは、QuickContains
は私のマシンのString.Contains
より約50%速いようです。
アップデート2(パフォーマンスの違いを説明)
私は多くのことを説明し、ベンチマークで不公平なものを発見しました。大文字と小文字を区別しない文字列を測定するベンチマーク自体でしたが、String.Contains
は大文字と小文字を区別した検索しか実行できないため、ToUpper
メソッドが含まれていました。これは結果を歪ませますが、少なくとも最終的な出力に関してではなく、少なくとも大文字小文字を区別しない検索ではString.Contains
のパフォーマンスを単純に測定する点では、
私はこの拡張メソッド
public static bool QuickContains(this string input, string value)
{
return input.IndexOf(value, 0, input.Length, StringComparison.Ordinal) >= 0;
}
2過負荷IndexOf
呼び出しで使用StringComparison.Ordinal
を使用してToUpper
を削除する場合だから今、QuickContains
方法は、実際には、最も遅いとなります。 IndexOf
とContains
は、パフォーマンス面でかなり上です。だから明らかにとIndexOf
の間にこのような不一致があった理由の結果を歪曲させてToUpper
呼び出しでした。
QuickContains
拡張メソッドが最も遅くなった理由がわかりません。(おそらく、Contains
には[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
という属性がありますか?)
4オーバーロードメソッドが直接呼び出されない理由はまだありますが、パフォーマンスによって影響を受けていないようです(Adrianとdelnanがコメントで指摘したように)。
これは、メソッドの呼び出しがコンパイラによってインライン化される可能性がありますので、任意の'String.Contains(文字列値)'の出現は、コードが実行されるまでにもっと複雑なバージョンに既に書き直されている可能性があります。しかし、これは明らかに単なる推測である。 –
それは良い考えです。私はちょうど最後のオーバーロードを直接呼び出す独自の 'Contains'メソッドを作成することでベンチマークを試みました。そして、それは既存の' Contains'メソッドよりも50%速くなったので、顕著なパフォーマンスヒットがあります。 1mループより200ms)。 – keyboardP
@keyboardP私は少し信じがたいことがわかります。最も単純なインライン・ヒューリスティックと最も単純なインライナーであっても、2つのバリアントを見分けがたいものにする必要があります。あなたは[ベンチマーキングミス](http://tech.pro/blog/1293/c-performance-benchmark-mistakes-part-one)をコミットしていませんか? – delnan