私のベンチマークはあなたのベンチマークと一致しません。
アレックスと同じベンチマークを実行したところ、反対の結果が得られました。次に、ベンチマークをいくらか微調整したところCast
、OfType
.
それほど多くはありませんがCast
、反復子がより単純であるため、当然のことながら、優位性があると思います。(is
チェックなし)
編集:実際には、さらに微調整した後Cast
、OfType
.
以下は、これまでに見つけた最大の不一致を示すベンチマークのコードです。
Stopwatch sw1 = new Stopwatch();
Stopwatch sw2 = new Stopwatch();
var ma = Enumerable.Range(1, 100000).Select(i => i.ToString()).ToArray();
var x = ma.OfType<string>().ToArray();
var y = ma.Cast<string>().ToArray();
for (int i = 0; i < 1000; i++)
{
if (i%2 == 0)
{
sw1.Start();
var arr = ma.OfType<string>().ToArray();
sw1.Stop();
sw2.Start();
var arr2 = ma.Cast<string>().ToArray();
sw2.Stop();
}
else
{
sw2.Start();
var arr2 = ma.Cast<string>().ToArray();
sw2.Stop();
sw1.Start();
var arr = ma.OfType<string>().ToArray();
sw1.Stop();
}
}
Console.WriteLine("OfType: " + sw1.ElapsedMilliseconds.ToString());
Console.WriteLine("Cast: " + sw2.ElapsedMilliseconds.ToString());
Console.ReadLine();
私が行った微調整:
- 「文字列のリストを生成する」作業を最初に一度行い、それを「結晶化」します。
- タイミングを開始する前に各操作の 1 つを実行します。これが必要かどうかはわかりませんが、JITter がタイミングを取っている間ではなく、事前にコードを生成することを意味していると思いますか?
- 各操作を 1 回だけでなく、複数回実行します。
- これが違いを生む場合に備えて、順序を変更します。
私のマシンでは、これにより が ~350ms、 がCast
~18000ms になりOfType
ます。
最大の違いはMatchCollection
、次の一致を見つけるのにかかる時間を計測しなくなったことです。(または、私のコードでは、どれくらいint.ToString()
時間がかかりますか。)これにより、信号対雑音比が大幅に低下します。
Cast
編集: sixlettervariablesが指摘したように、この大きな違いの理由は、IEnumerable
. Regex.Matches
正規表現の処理時間を測定することを避けるために使用から配列に切り替えたときに、キャスト可能なものを使用するように切り替えたためIEnumerable<string>
、この短絡がアクティブになりました。ベンチマークを変更してこのショートサーキットを無効にすると、大きなアドバンテージではなく、わずかなアドバンテージが得られます。Cast