2011-05-03 109 views
4

上下文是我在內存中有一組緩存取值很高的值,另一組相關數據的取回並且無法緩存(業務規則) 。我知道了所有的工作,但我只是想知道如果任何人都可以想到做這樣的更新的更經濟的方式...比較和更新C#中的兩個列表

foreach (var nonCachedItem in searchItemsNonCached) 
    { 
     foreach (var cachedItem in searchItemsCached) 
     { 
      if (cachedItem.ID == nonCachedItem.ID) 
       nonCachedItem.Description = cachedItem.Description; 
     } 
    } 

它基本上只是與信息高速緩存的信息匹配我得到了。這一切都有效,負載幾乎可以忽略不計,但我對提高效率很感興趣。

編輯:在上面,searchItemsNonCached和searchItemsCached都是SearchItem列表,其中Searchitem是一個定製的對象。

+3

searchItemsNonCached和searchItemCached的類型是什麼?他們有更快的搜索比O(n)?他們排序了嗎? – 2011-05-03 13:29:31

+0

,您可以使用並行化是搜索 – 2011-05-03 13:34:25

回答

2

加載一個Dictionary與緩存的項目,然後通過循環每個非緩存項尋找在字典中的比賽。這是O(n)而不是嵌套循環,它是O(n^2)

var cachedDictionary = new Dictionary<int, YourType>(); 
foreach (var item in searchItemsCached) 
{ 
    cachedDictionary.Add(item.ID, item); 
} 
foreach (var item in searchItemsNonCached) 
{ 
    YourType match; 
    if (cachedDictionary.TryGetValue(out match)) 
    { 
    item.Description = match.Description; 
    } 
} 

如果你可以考慮使用緩存項Dictionary從一開始(而不是List),那麼你可能會避免發現在比賽前加載它的步驟。

5

將您的緩存項目存儲在字典中。現在只有鑰匙存在時纔可以更新。

-1

另一種方法是您可以編寫一個linq表達式並將ID列表上的兩個列表連接起來,並使用更新的值創建具有相同類型的新對象。

from nc in searchItemsNonCached 
join c in searchItemCached on nc.ID equals c.ID 
select new (same type) // and assign the desc from c.Description 
0

什麼你正在試圖做的基本上是一個連接(在數據庫意義上的),特別是等值連接的。您可以在連接算法上查看this section of a Wikipedia article。上面列出的代碼是一個嵌套循環連接,adymitruk的建議是散列連接,但Lou Franco評論說,最好的方法可能取決於您的集合具有什麼樣的排序或結構(如果有)。

如果searchItemCached只是一個無序列表,那麼hash join可能是您最好的選擇 - 只需從一個集合或另一個以ID爲關鍵字創建字典,然後循環查看其他集合,查找匹配項從字典中。如果searchItemCached已經是一個以ID爲鍵的字典,那麼散列連接就是,絕對是是你最好的選擇。如果searchItemCachedsearchItemsNonCached都是按ID排序的,那麼sort-merge join可能是要走的路。

+0

哈希另一個功能加入使用了大量的記憶,他應該意識到這一點,但該命令是兩個輸入數的總和。 O(input1.count + input2.count)。 – 2011-05-03 13:50:41

+0

@Gabriel好一點,這裏有一個時空權衡。但如果'searchItemCached'已經是一本字典,則不需要任何額外的空間。 – Aaron 2011-05-03 13:53:03

+0

對不起應該提到的是,他們是定製的對象 – 2011-05-03 14:02:25