2016-11-16 5 views
0

私はアイテムのリストを持っており、それらのサブセットを反復したいと思います。さて、私は、リストから不要なアイテムを削除してからそれをループするときに、パフォーマンスに影響があるかどうかは分かりません。 forループ内のリストを単にフィルタリングすることもできます。.RemoveAllと.ChereのC#のパフォーマンスの差

ここは例です。

REMOVEALLアプローチ:

list.RemoveAll(o => !someOtherList.Contains(o.Property)); 

foreach (var i in list) 
{ 
} 

アプローチザ・:

foreach (var i in list.Where(o => someOtherList.Contains(o.Property)) 
{ 
} 

私は最初のアプローチは、実際にどこ秒1がないので、リストにあるものを操作しようとしていることを理解します。それは本当に私には関係しません。私は、第2のアプローチのフィルタが各反復に適用されるかどうか、またはC#がサブセットを作成してそのサブセットをループするだけであるかどうかについて懸念しています。 Iは第2のアプローチでは、フィルタがほぼ有する第 アプローチと同様に(各反復またはC#はそのサブセットを介し サブセットのみループを作成するのに十分スマートであるか否かを 適用されるか否かのより心配

+0

「someOtherList.Contains」が何回呼び出されるのでしょうか?という質問がある場合、私はその答えが両方のサンプルで同じであると強く思っています。 –

+2

どちらが速いのですか?両方を1000回実行し、平均を計算してください! – user3185569

+0

@Damien_The_Unbeliever:私の質問は何回list.Whereに呼び出されますか? – Johannes

答えて

5

一時変数)

のLINQのWhereは一度要求された時間での要素1を返すためにyieldを使用しています。

だから、実際には第二のアプローチで行われているものです。リストを

の1-反復

2 - チェック、それは特別な場合を除き、現在の要素が条件someOtherListて(ループに一致した場合検索データ構造など。HashSet

3 - 私たちは最初の要素は

、4-それを返す見つけたらは、foreachの本体のロジックを実行

5-我々はあなたがするforeachブロック内のいくつかの条件に基づいて分割することを決めた場合、多分すべてのリストは、いくつかのケースでは、その時点でスキャンすることができるではない意味ステップ3

で停止したところから検索を続けます大きなリストのパフォーマンスを向上させる可能性があります。

+0

ありがとう、それはうまく説明します。 – Johannes

1

他の人が既に述べたことに加えて、ループの操作があなたが示したようなものであれば、未処理のパフォーマンスでは無視できない違いはありません。

ただし、最初はマテリアライズドリストが必要ですが、後者はIEnumerableで動作します。また、ループコンテンツが動作するためには、まずループコンテンツが開始されない限り、最初に実現する必要があります。 IOWをNOPループで実行すると、リストとanotherListの両方で10秒かかることがあります。ループ内に何らかの作業がある場合(おそらく)、最初の作業はループに入る前に10秒を費やしており、ループで処理する時間が必要です。後者のOTOHは、見つかった各要素のループを直接起動します。ループの内容が時間のかかる操作であり、さらに非同期で実行できる場合は、後者が明確な勝者になります。

関連する問題