3

LINQを使用して以下を書き直そうとしています

foreach (WMCommon.Services.StakeOut.assembly ass in assemblies) 
{
  foreach (var agg in aggregate) 
  {
    if ( agg.catagory.unitActn   == ass.unitActn   &&
         agg.catagory.unitCode   == ass.unitCode   &&
         agg.catagory.unitLength == ass.unitLength
    ) 
    {
      ass.quantity = agg.qty;
    }
  }
}

これは私が得た限りです:

assemblies.Where( a => a.quantity = ( aggregate.Where( p => p.catagory.unitActn == a.unitActn && p.catagory.unitCode == a.unitCode && p.catagory.unitLength == a.unitLength).Select(s=>s.qty)));

よろしくお願いいたします。LINQ がネストされた FOREACH よりもはるかに高速になることを願っていますか?

4

3 に答える 3

7

LINQ がネストされた FOREACH よりもはるかに高速になることを願っていますか?

一般に、LINQ の動作を変更しない限り、LINQ によってパフォーマンスが向上することはありません。LINQ は効果的に繰り返しを実行しているだけです。

この場合、結合を使用してこれを全体的に改善できるように見えます。これにより、同じ効果が得られるからです。

var query = from WMCommon.Services.StakeOut.assembly ass in assemblies
            join agg in aggregate
            on new { ass.unitActn, ass.unitCode, ass.unitLength } equals new { (agg.catagory.unitActn, agg.catagory.unitCode, agg.catagory.unitLength }
            select new { ass, agg };

foreach(var pair in query)
    pair.ass.quantity = pair.agg.qty;
于 2013-08-20T16:42:18.667 に答える
1

なぜリンク?あなたが持っているものよりも速くなることはまずありません。あなたが持っているものよりも単純で読みやすく、デバッグしやすいということはまずありません。

パフォーマンスを向上させたい場合、ネストされたループは O(mn) 時間で実行されます。ここで、mはアセンブリ コレクションのサイズ、nは集計コレクションのサイズであるため、基本的に O(n 2 ) 時間です。

コレクションはキー値で並べられていますか? もしそうなら、ロックステップで 2 つのコレクションを反復することによって 2 つのコレクションをマージすることは大きな勝利となります。これにより、O(n) パフォーマンスのような結果が得られるはずです。

それらが順序付けられていない場合は、アセンブリ コレクションを反復処理する前に、集計コレクションを取得してディクショナリのようなルックアップ テーブルに変換することで勝利を収めることができます。次に、辞書に対するおそらく高速なルックアップを使用して、アセンブリを直接反復します。

于 2013-08-20T17:27:45.397 に答える
0

これを試して:

assemblies.ForEach(a => a.quantity = (aggregate.Where(p => p.catagory.unitActn == a.unitActn && p.catagory.unitCode == a.unitCode && p.catagory.unitLength == a.unitLength).Select(s=>s.qty)));

しかし、それは速くないことに注意してください

于 2013-08-20T16:39:36.633 に答える