0
            Stopwatch sw = new Stopwatch();
            for (int i = 0; i < lines.Length; i++)
            {
                sw.Start();
                fn(); //call function
                sw.Stop();

            }
            Console.WriteLine(sw.ElapsedMilliseconds);


            long total =0;
            for (int i = 0; i < lines.Length; i++)
            {
                Stopwatch sw = Stopwatch.StartNew();
                fn(); //call function
                sw.Stop();
                total += sw.ElapsedMilliseconds;

            }
            Console.WriteLine(total);

出力が同じではありません。それについて何か説明はありますか?

4

4 に答える 4

8

2 番目のループで大量のオブジェクトを作成しているなどの事実は別として、ガベージ コレクション内で簡単にガベージ コレクションが発生しfn()たり、他の何かによって実際にタイミングが長くなったりする可能性があります。また、各反復の経過ミリ秒も取っているだけです。2番目のケース。

各反復に 0.1 ミリ秒かかるとします。2 番目のループの合計は 0 になります。これは、反復ごとに経過時間が 0 ミリ秒に切り捨てられるためです。最初のループは、経過したticksを追跡します。

これはすべて脇に置いておきますが、タイマーをこれほど頻繁に開始および停止するべきではありません。結果台無しになります。代わりに、ストップウォッチをループの前に 1 回開始し、ループの後に停止します。

ループのオーバーヘッドを取り除きたい場合は、単純にのループの時間を計ってオーバーヘッドを見つけ、実際の作業を含むループでかかった時間からそれを差し引きます。実際の CPU にはさまざまな複雑さ (キャッシュ ミスなど) があるため、それほど単純ではありません、率直に言って、マイクロベンチマークはその点で特に正確ではありません。何よりもガイドとして使用する必要があります。

于 2010-11-03T15:45:23.920 に答える
4

StartNew()Stop()がオーバーヘッドを作成するためです。これが、実際のパフォーマンス測定のパフォーマンス オーバーヘッドを最小限に抑えるために、通常、数百回または数千回の反復でこの種のテストを行う理由です。

于 2010-11-03T15:37:45.060 に答える
1

おそらく、システム タイマーの粒度に達している可能性があります。些細な関数のタイミングを計ると、0 ミリ秒または 10 ミリ秒が返されることがあります。このエラーは、テストに追加される可能性があります。

最初のループを 2 回実行した場合、または 2 番目のループも 2 回実行した場合、おそらく同様の結果が得られるでしょう。

于 2010-11-03T15:42:17.633 に答える
1

ループのオーバーヘッドは、タイマーを繰り返し停止/開始するオーバーヘッドよりもかなり小さくなり、新しいタイマーを繰り返し作成する場合はさらに少なくなります。そのため、ループの前にタイマーを開始し、ループの後に終了し、経過時間を反復回数で割ります。はるかに正確な結果が得られます。

于 2010-11-03T15:44:52.637 に答える