2009-03-23 16 views
27

私は特定のパラメータに基づいて項目を見つけるための一般的なリストを探しています。一般的なリストFindAll()とforeach

一般的に、最も優れた、最も速い実装は何ですか?
1.リストの各項目をループして、新しいリストへの各試合を節約し、

foreach(string s in list) 
{ 
    if(s == "match") 
    { 
     newList.Add(s); 
    } 
} 

return newList; 

それとも
2. FindAllメソッドを使用し、それにデリゲートを渡すことを返します。

newList = list.FindAll(delegate(string s){return s == "match";}); 

どちらも〜O(N)で実行しないでください。ここでベストプラクティスは何ですか?

よろしく、 ジョナサン

答えて

41

FindAllメソッドまたは同等のLINQメソッドを使用する必要があります。また、C#3が必要な場合は、代理人の代わりに簡潔なラムダを使用することを検討してください。0):

var list = new List<string>(); 
var newList = list.FindAll(s => s.Equals("match")); 
9

私はそれがより簡潔であるように、この場合にはFindAll methodを使用し、IMO、読みやすくしています。 foreach statementがわずか速く(代表者がわずかながかかり、それは、デリゲートの呼び出しを実行する必要はありません与えられるべきであるが、

あなたは、彼らはかなりの両方に行っていることを正しいとは、O(N)時間で実行しますオーバヘッドはメソッドを直接呼び出すのではなく)。

私はこの差が、おそらくより多くのあなたが大規模なリストに対する操作の膨大な数を行っている場合を除き違いを確認するつもりはありませんですが、どのように些細強調しなければなりません。

いつものように、ボトルネックがどこにあるのかを確認し、適切に行動してください。

4

List.FindAllはO(n)であり、リスト全体を検索します。

foreachで独自のイテレータを実行する場合は、yield文を使用し、可能であればIEnumerableを返すことをおすすめします。この方法では、コレクションの要素を1つだけ必要とする場合は、コレクション全体を使い果たすことなく呼び出し元を停止できるので、コレクションの要素がより速くなります。

それ以外の場合は、BCLインターフェイスに固執します。

3

いずれかの差異の差はごくわずかです。わかりやすく、または可能であれば、Enumerable.WhereのFindAllを提案します。私はEnumerableメソッドを使う方が好きです。なぜなら、コードのリファクタリングに柔軟性を持たせることができるからです(あなたはList<T>に依存しません)。

5

ジョナサン、あなたはこれに見つけることができます

良い答えはLinq To Actionの第5章(パフォーマンスの考慮)です。

約50回実行される検索ごとにaを測定し、それは1サイクルあたりforeach = 68ms/1サイクルあたりList.FindAll = 62msで表示されます。実際には、テストを作成して自分自身で確認するだけで、おそらくあなたの関心事になるでしょう。

2

はい、両方の実装はO(n)です。彼らはすべてのマッチを見つけるためにリストのすべての要素を調べる必要があります。読みやすさの面ではFindAllも好きです。性能については、LINQ in Action(Ch 5.3)を参照してください。 C#3.0を使用している場合は、ラムダ式を適用することもできます。しかし、それはケーキの上だけでアイシングです:

var newList = aList.FindAll(s => s == "match"); 
1

ラムダ

List<String> newList = list.FindAll(s => s.Equals("match")); 
0

とイムC#のチームはLINQFindAllのパフォーマンスを改善しない限り、以下の記事がforこととforeachを示唆しているようですオブジェクトの列挙でLINQFindAllLINQ on Objects Performanceより優れています。

このartilceは、この投稿が最初に尋ねられる直前の2009年3月のものです。

関連する問題