5

遅延実行についてはほとんど理解していますが、特定のケースについて質問があります。

次のようなコードフラグメントが与えられた場合

                        var resultsOfInterest = from r in ...
                                                select r;
                        foreach (var x in resultsOfInterest)
                        {
                            //do something with x
                        }

クエリresultsOfInterestが実行された回数は ? foreach ループを設定するときに 1 回、または要素 'x' ごとに 1 回ですか? より効率的でしょうか

                        foreach (var x in resultsOfInterest.ToArray())
                        {
                            //do something with x
                        }

?

ティア

4

3 に答える 3

5

GetEnumerator()メソッドがクエリ変数に対して実行されるときに、ループの前に一度実行されます。foreachループは次のようになります。

var enumerator = resultsOfInterest.GetEnumerator(); // query executed here

while(enumerator.MoveNext()) // iterating over results of query execution
{
   var x = enumerator.Current;
   // do something with x
}

2 番目のサンプルはより効率的ではありません。単純にクエリ実行の結果を配列に格納してから、配列反復子を呼び出します。

var enumerator = resultsOfInterest.ToArray().GetEnumerator();
// loop stays same
于 2013-09-04T14:21:00.193 に答える
0

どちらの場合も、クエリは 1 回だけ実行されますが、2 番目のケースでは 2 つの列挙があります。

1000 個のアイテムがあると仮定すると、次のようになります。

ケース 1:

  1. 句を実行し、select結果を に代入しxます。
  2. Goto 1 を 1000 回繰り返します。

ケース 2:

  1. アレイを作成します。
  2. 句を実行し、select結果を配列に代入します。
  3. 後藤 2、1000 回繰り返します。
  4. 配列から要素にアクセスし、に割り当てxます。
  5. 後藤 4、1000 回繰り返します。

したがって、一般に、配列を作成することはまったく望ましくありません。しかし、同じアイテムを自分で複数回列挙する必要があり、配列アクセスが よりも高速である場合はselect、もちろん、配列を作成する方が効率的です。

于 2013-09-04T15:13:45.270 に答える