4


リストには約 200K のレコードがあり、それらをループして別のコレクションを形成しています。これは、ローカルの 64 ビット Win 7 では正常に動作しますが、Windows Server 2008 R2 に移動すると、かなりの時間がかかります。ほぼ1時間ほどの差があります!

Compiled Queries を調べてみましたが、まだ解決していません。
さまざまな理由により、データベースを結合して子の値を取得することはできません

コードは次のとおりです。

//listOfDetails is another collection
List<SomeDetails> myDetails = null;
foreach (CustomerDetails myItem in customerDetails)
{

    var myList = from ss in listOfDetails
                 where ss.CustomerNumber == myItem.CustomerNum
                 && ss.ID == myItem.ID
                 select ss;
     myDetails = (List<SomeDetails>)(myList.ToList());
     myItem.SomeDetails = myDetails;
}
4

4 に答える 4

7

私はこれを別の方法で行います:

var lookup = listOfDetails.ToLookup(x => new { x.CustomerNumber, x.ID });
foreach(var item in customerDetails)
{
    var key = new { CustomerNumber = item.CustomerNum, item.ID };
    item.SomeDetails = lookup[key].ToList();
}

このコードの大きな利点はlistOfDetails、ルックアップを構築するために 1 回だけループする必要があることです。これはハッシュ マップにすぎません。その後、キーを使用して値を取得するだけです。これは、ハッシュマップが構築されているため、非常に高速です。

于 2012-09-11T16:57:35.187 に答える
4

パフォーマンスに違いがある理由はわかりませんが、そのコードのパフォーマンスを向上させることができるはずです。

//listOfDetails is another collection
List<SomeDetails> myDetails = ...;
detailsGrouped = myDetails.ToLookup(x => new { x.CustomerNumber, x.ID });
foreach (CustomerDetails myItem in customerDetails)
{ 
    var myList = detailsGrouped[new { CustomerNumber = myItem.CustomerNum, myItem.ID }];
    myItem.SomeDetails = myList.ToList();
}

ここでの考え方は、 で繰り返されるループを回避し、myDetails代わりにハッシュ ベースのルックアップを構築することです。それが構築されると、ルックアップを行うのは非常に安価です。

于 2012-09-11T16:55:59.853 に答える
1

私はあなたがおそらくここに参加することから利益を得るだろうと思うので:

var mods = customerDetails
    .Join(
        listOfDetails, 
        x => Tuple.Create(x.ID, x.CustomerNum), 
        x => Tuple.Create(x.ID, x.CustomerNumber),
        (a, b) => new {custDet = a, listDet = b})
    .GroupBy(x => x.custDet)
    .Select(g => new{custDet = g.Key,items = g.Select(x => x.listDet).ToList()});

foreach(var mod in mods)
{
    mod.custDet.SomeDetails = mod.items;
}

私はこのコードをコンパイルしませんでした...

結合を使用すると、あるリストのアイテムを別のリストと照合するためにLookup、O(n)時間で2番目のリストのハッシュテーブルのようなコレクション()を作成します。次に、最初のリストを繰り返し、からアイテムをプルしますLookup。ハッシュテーブルからのデータのプルはO(1)であるため、反復/一致フェーズでも、後続のGroupByと同様に、O(n)のみが必要です。したがって、すべての操作で、O(n)と同等の〜O(3n)を使用する必要があります。ここで、nは長い方のリストの長さです。

于 2012-09-11T17:30:28.000 に答える
1

内部のToList()は、各ループの評価を強制しますが、これは問題になります。SelectManyを使用すると、次のようなToListを回避できる場合があります。

var details = customerDetails.Select( item => listOfDetails
    .Where( detail => detail.CustomerNumber == item.CustomerNum)
    .Where( detail => detail.ID == item.ID)
    .SelectMany( i => i as SomeDetails )
);

最初にすべてのSomeDetailsを取得してから、それらをアイテムに割り当てると、速度が上がる可能性があります。またはそうではないかもしれません。あなたは本当に時間がかかっている場所を見るためにプロファイリングする必要があります。

于 2012-09-11T17:01:19.260 に答える