2011-07-06 9 views
2

私が開発していますサイトのパフォーマンスを見ていたと私は私が書いたいくつかのコードに出くわした:上記のコードでメソッドの実行が

foreach (WorkItem wi in p.getWorkItems(dateFrom, dateTo)) 
{ 
    someFunction(wi); 
} 

p.getWorkItems方法は毎回実行さありませんループは実行されますか?または、それは一度実行され、結果オブジェクトをメモリに保持し、オブジェクトを使用しているポインタをインクリメントするだけですか?その理由は、getWorkItemsは大量のシーン(比較、並べ替え、他のクエリ)をしているので、これを何度も実行しない方がよいでしょう。その場合は、私は以下のようにそれをやったほうが良いと思います:

List<WorkItem> workload = p.getWorkItems(dateFrom, dateTo); 

for (int i = 0; i < workload.Count; i++) 
{ 
    someFunction(workload[i]); 
} 

それは、C#で書かれていますが、私は答えが最も類似の言語に適用されることを想定しています。..

+2

'p.getWorkItems'が毎回実行される場合、' in'はどのように結果を反復処理しますか? –

答えて

4

foreachループがどのようにC#コードに変換されるのかを理解する必要があります。 C#言語仕様の8.8.4からは、あなたのループ

foreach (WorkItem wi in p.getWorkItems(dateFrom, dateTo)) { 
    someFunction(wi); 
} 

var enumerator = p.getWorkItems(dateFrom, dateTo).GetEnumerator(); 
try { 
    WorkItem wi; 
    while(enumerator.MoveNext()) { 
     wi = (WorkItem)enumerator.Current; 
     someFunction(wi); 
    } 
} 
finally { 
    IDisposable disposable = enumerator as System.IDisposable; 
    if (disposable != null) disposable.Dispose(); 
} 

なっしたがって、p.getWorkItemsが正確に一度だけ実行されることは明らかです。

1

または、それは一度実行され、結果オブジェクトをメモリに保持し、オブジェクトを使用しているポインタをインクリメントするだけですか?

はい(*)print文をgetWorkItemsに置くことでこれを証明できます。

(*)結果オブジェクトがgetWorkItemsを再帰的に呼び出さない限り、

1

p.getWorkItemsが1回だけ呼び出されます。結果はメモリに格納され、foreachループはメモリ内の結果オブジェクトに対して反復処理を行います。

これが当てはまらない場合、メソッドが新しいリストを返すたびにforeachが終了することはありません。

関連する問題