2011-07-13 14 views
1

次のLINQステートメントは、特定のプロパティに対して重複する値を持つ項目を検出し、countでグループ化し、次にブール値を戻す別のグループ化を行います。どのようにこのLINQ文を高速化するために最適化できますか?

これはどのように改善することができますか、それは少し無駄に思われます。これはオブジェクトモデルの検証ライブラリの一部なので、できるだけ早くそれを得ることができます。

実行のスピードが優先されますが、他の提案も歓迎します。

var grouped = from g2 in 
       (from i in item.ParentList 
        where _filter(i) 
        group i by propGetter(i) into g 
        select new { Count = g.Count(), Items = g }) 
       group g2 by g2.Count == 1 into g3 
       select new { IsUnique = g3.Key, Items = g3 }; 

foreach (var g in grouped) 
{ 
    foreach (var grp in g.Items) 
    { 
     foreach (var itm in grp.Items) 
     { 
      if (g.IsUnique == false) 
       itm.AddPropertyError(_propertyName, (int)Validations.Unique, _message); 
      else 
       itm.RemovePropertyError(_propertyName, (int)Validations.Unique); 
     } 
    } 
} 
+1

どのような改善がありましたか? – Oded

+1

あなたは直面しているパフォーマンスヒットは何ですか? – V4Vendetta

+0

申し訳ありません。質問を編集して詳細を追加しました。私は実際に顕著なパフォーマンスヒットを経験していない、ちょうど(私に)少し無駄に見える。私は決してLINQの専門家ではありません。 – Marlon

答えて

2

オスカーは、プロファイリングは、それが問題を引き起こしていることを示していない限り、あなたはおそらく、スピードのクエリを最適化するためにしたくない、言ったように。 Premature optimization is the root of all evil。あなたが読みやすくするために、クエリを最適化したい場合は、ここに第二部を簡素化する一つの方法は次のとおりです。あなたのコメントについて

var items = grouped 
    .SelectMany(group => group.Items) 
    .SelectMany(group => group.Items) 

foreach (var item in items) 
{ 
    ... 
} 

編集:ああ、私はあなたが最も内側のループ内g.IsUniqueを参照していることに気づいていませんでした。 3段階のインデントなしでこの問題を解決する方法の1つですが、最良の方法ではない可能性があります。

var uniqueItems = grouped 
    .Where(group => group.IsUnique) 
    .SelectMany(group => group.Items) 
    .SelectMany(group => group.Items) 

var nonUniqueItems = grouped 
    .Where(group => !group.IsUnique) 
    .SelectMany(group => group.Items) 
    .SelectMany(group => group.Items) 

foreach (var item in uniqueItems) 
{ 
    ... 
} 

foreach (var item in nonUniqueItems) 
{ 
    ... 
} 
+1

これは、可読性のために最適化する方法です。ネスティングの3つのレベルは、一般的に読みにくく、変更するのが難しいです。 – KevDog

+0

それでもブールキーを取得できますか? – Marlon

+0

@マールロン:私の編集を参照してください。 –

関連する問題