質問

    

この質問にはすでに回答があります:

         

C#でメソッド呼び出しをベンチマークする方法を探しています。

大学の割り当てのためにデータ構造をコーディングしましたが、少し最適化する方法を思いつきましたが、O(n)呼び出しをOに変えながら、すべての状況で少しオーバーヘッドを追加する方法で(1)一部。

次に、テストデータに対して両方のバージョンを実行して、最適化を実装する価値があるかどうかを確認します。 Rubyでは、コードをBenchmarkブロックでラップし、コンソールでブロックを実行するのに必要な時間を出力させることができることを知っています-C#で利用可能なものがありますか?

役に立ちましたか?

解決

組み込みのストップウォッチクラスを使用して、 "経過時間を正確に測定するために使用できるメソッドとプロパティのセットを提供します。"手動で行う方法を探している場合。ただし、自動化については不明です。

他のヒント

Yuriyの答えから盗まれた(および変更された):

private static void Benchmark(Action act, int iterations)
{
    GC.Collect();
    act.Invoke(); // run once outside of loop to avoid initialization costs
    Stopwatch sw = Stopwatch.StartNew();
    for (int i = 0; i < iterations; i++)
    {
        act.Invoke();
    }
    sw.Stop();
    Console.WriteLine((sw.ElapsedMilliseconds / iterations).ToString());
}

多くの場合、特定のメソッドはいくつかのものを初期化する必要があり、それらの初期化コストを全体的なベンチマークに常に含める必要はありません。また、合計実行時間を反復回数で除算することで、推定が反復回数にほぼ依存しないようにします。

ベンチマークのJon Skeetの方法から次のほとんどを盗みました:

private static void Benchmark(Action act, int interval)
{
    GC.Collect();
    Stopwatch sw = Stopwatch.StartNew();
    for (int i = 0; i < interval; i++)
    {
        act.Invoke();
    }
    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds);
}

これは、試行錯誤によって見つけたものです。

  1. (数千)回の反復の最初のバッチを破棄します。 JITterの影響を受ける可能性が高いです。
  2. 別の Thread オブジェクトでベンチマークを実行すると、より安定した結果が得られます。理由はわかりません。
  3. ベンチマークを実行する前に、何らかの理由で Thread.Sleep を使用している人を見かけました。これは事態を悪化させるだけです。理由はわかりません。おそらくJITterによるものです。
  4. デバッグを有効にしてベンチマークを実行しないでください。コードは、おそらく桁違いに遅く実行されます。
  5. すべての最適化を有効にしてアプリケーションをコンパイルします。一部のコードは最適化の影響を大きく受ける場合がありますが、他のコードは影響しないため、最適化せずにコンパイルするとベンチマークの信頼性に影響します。
  6. 最適化を有効にしてコンパイルする場合、ベンチマークの出力を何らかの方法で評価する必要がある場合があります(たとえば、値を出力するなど)。そうしないと、コンパイラは一部の計算が役に立たず、単に実行されないだけで、「数字を消してしまう」可能性があります。
  7. 特定のベンチマークを実行すると、デリゲートの呼び出しに顕著なオーバーヘッドが生じる可能性があります。デリゲート内に複数の反復を配置することをお勧めします。これにより、オーバーヘッドがベンチマークの結果にほとんど影響しません。
  8. プロファイラーは、独自のオーバーヘッドを持つことができます。コードのどの部分がボトルネックであるかを伝えるのは得意ですが、実際に2つの異なるものを確実にベンチマークするのは得意ではありません。
  9. 一般に、派手なベンチマークソリューションには顕著なオーバーヘッドがあります。たとえば、1つのインターフェイスを使用して多くのオブジェクトのベンチマークを行いたい場合、クラス内のすべてのオブジェクトをラップしたくなるかもしれません。ただし、クラスコンストラクターにもオーバーヘッドを考慮する必要があることに注意してください。すべてをできるだけシンプルで直接的なものにすることをお勧めします。

プロファイラーが必要なようです。 EQATECプロファイラーを自分で試してみることを強くお勧めします。このメソッドの単純なストップウォッチに対する優れた点は、特定のメソッド/ブロックのパフォーマンスの内訳も提供することです。

プロファイラーはすべてのコードを診断するため、最高のベンチマークを提供しますが、速度が大幅に低下します。プロファイラーは、ボトルネックを見つけるために使用されます。

アルゴリズムを最適化するために、ボトルネックがどこにあるかがわかっている場合、名前の辞書を使用してください-&gt; stopwatch、実行中のパフォーマンスクリティカルセクションを追跡します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top