5

プロジェクトに取り組んでいるときに、次のコードに遭遇しました。これにより、パフォーマンス フラグが発生しました。

foreach (var sample in List.Where(x => !x.Value.Equals("Not Reviewed")))
{
    //do other work here
    count++;
}

元のループと次のループを比較する簡単なテストをいくつか実行することにしました。

foreach (var sample in List)
{
    if (!sample.Value.Equals("Not Reviewed"))
    {
        //do other work here
        count++;
    }
}

このループも投げて、何が起こるかを確認します。

var tempList = List.Where(x => !x.Value.Equals("Not Reviewed"));
foreach (var sample in tempList)
{
    //do other work here
    count++;
}

また、元のリストに 3 つの異なる方法で入力しました: 50-50 (つまり、値の 50% が「未レビュー」で残りがその他)、10-90 および 90-10。これらは私の結果です。最初と最後のループはほとんど同じですが、2 番目のループは特に 10-90 の場合にはるかに高速です。なぜ正確に?Lambdaパフォーマンスがいいとずっと思っていました。

編集

は実際にはループ内にあるものではありません。count++デモンストレーションのためにここに追加しただけです。「//do something here」を使用する必要があったと思います。

パフォーマンス結果

編集2

それぞれを 1000 回実行した結果: 実績 1000回

4

1 に答える 1

9

基本的に、デリゲートを介したテストと反復部分の両方に、少量の追加の間接化があります。反復ごとに実行される作業がどれだけ少ないかを考えると、その余分な間接化は比較的高価です。

私の見解では、それは驚くべきことでも心配なことでもありません。これは、実際のアプリケーションで重要になるというまれな状況にある場合に、簡単に実行できる種類のマイクロ最適化です。私の経験では、この種のループがアプリの重大なボトルネックになることはほとんどありません。通常のアプローチは次のとおりです。

  • パフォーマンス要件の定義
  • できる限り明確でシンプルな方法で機能要件を実装する
  • 要件に対するパフォーマンスを測定する
  • パフォーマンスが不十分であることが判明した場合は、その理由を調査し、明確さからできるだけ離れて、可能な限り最大の「費用対効果」を得る
  • 完了するまで繰り返します

編集への対応:

count++ は実際にはループ内にあるものではありません。デモンストレーションのためにここに追加しただけです。「//do something here」を使用する必要があったと思います。

それが重要な部分です。そこで行われる作業が多ければ多いほど、他のことは重要ではなくなります。カウントするだけでもかなり速いので、大きな差異が見られると思います。実際の作業をいくらでも行えば、差は小さくなります。

于 2013-07-18T15:42:26.743 に答える