2016-12-22 3 views
2

ここではパフォーマンスに問題があります。私はそのことでWholeSaleEntryフィルタリングする必要フィルタリスト1リスト2

public class WholeSaleEntry 
{ 
    public string SKU { get; set; } 
    public string Stock { get; set; } 
    public string Price { get; set; } 
    public string EAN { get; set; } 
} 

とProductList

public class ProductList 
{ 
    public string SKU { get; set; } 
    public string Price { get; set; } 
    public string FinalPrice { get; set; } 
    public string AlternateID { get; set; } 

} 

あるWholeSaleEntry

私がリストになった(50K項目)が含まれ とリスト(120K項目)が含まれてい

EANとSKUがEANまたはSKUがProductList.AlternateIDの場合には、 私はこのコードを書いたが、perf ormanceは本当に遅いです

 List<WholeSaleEntry> filterWholeSale(List<WholeSaleEntry> wholeSaleEntry, List<ProductList> productList) 
    { 
     List<WholeSaleEntry> list = new List<WholeSaleEntry>(); 
     foreach (WholeSaleEntry item in wholeSaleEntry) 
     { 
      try 
      { 
       string productSku = item.SKU; 
       string productEan = item.EAN; 
       var filteredCollection = productList.Where(itemx => (itemx.AlternateID == productEan) || (itemx.AlternateID == productSku)).ToList(); 

       if (filteredCollection.Count > 0) 
       { 
        list.Add(item); 
       } 
      } 
      catch (Exception) 
      { 
      } 
     } 

     return list; 
    } 

フィルタリングの方法はありますか、それとも一括でフィルタリングできるものはありますか?

+0

まず、「Where」ではなく「Any」を使用します。すべてのレコードをフィルタリングし、カウントを確認する場所。 Anyでは、最初の一致でフィルタリングを停止します。それで 'if(productList.Any(item => ...))list.Add(item);' – Reniuz

+0

私はそれを一度も使っていません。正直なところ私は試してみましたが、私のコードでそれを実装する方法を理解できませんでした –

+0

私はちょうどどこかに変更する必要がありますか? –

答えて

6

.Where(...).ToList()を使用すると、一致するすべてのアイテムが見つかり、最終的に一致するアイテムがあるかどうかを知る必要があります。

var hasAny = productList.Any(itemx => itemx.AlternateID == productEan || itemx.AlternateID == productSku); 
if (hasAny) 
{ 
    list.Add(item); 
} 


更新:アルゴリズムは、このように単純化することができるが、このように、とすぐに一致するものが見つかったとして、停止しAny(...)を使用して固定することができます。最初に、HashSetを使用して一意の代替IDを取得します。これは、重複した項目を1回だけ格納し、ルックアップには狂気です。その後、それに合致するWholeSaleアイテムをすべて取得します。
より高速な戦略はなく、コードは小さく、わかりやすいと思います。

var uniqueAlternateIDs = new HashSet<string>(productList.Select(w => w.AlternateID)); 
var list = wholeSaleEntry 
    .Where(w => uniqueAlternateIDs.Contains(w.SKU) 
      || uniqueAlternateIDs.Contains(w.EAN)) 
    .ToList(); 
return list; 

簡単なテストは、50K + 50Kの項目について、HashSet<string>を使用して答えを得るために28msを取ったことを明らかにしました。 .Distinct().ToList()で塗りつぶしたList<string>を使用すると、他のコードはすべて同じで、48秒かかりました。

+2

理論的にはうれしいですが、50k回の120kアイテムすべてにわたってループしている最悪のケースです。 – CodeCaster

+1

あなたの編集にそのコードの 'HashSet 'が必要で、これはリストよりも速い検索を提供します。 – CodeCaster

+1

ありがとう、良い計画のように聞こえる、私はそれを使用していないので、私が知っているものと一緒に行かなければならなかった。 –

1

特定の方法を必要とせず、リストを避けたい場合は、これを実行してください。

var filteredWholeSale = wholeSaleEntry.Where(x => productList.Any(itemx => itemx.AlternateID == x.EAN || itemx.AlternateID == x.SKU)); 
+1

@コードキャスター。十分に公正で、私は理由を付け加えました。既に提供されているのと同じソリューションではありません – SJFJ

関連する問題