2008-12-15 25 views
3

我必須研究一些使用泛型列表來存儲自定義對象集合的代碼。檢查通用列表內容的最佳方法

隨後,它類似於下面的集合中,以檢查是否一個給定對象的和做的東西,如果這樣:

List<CustomObject> customObjects; 
//fill up the list 
List<CustomObject> anotherListofCustomObjects; 
//fill it up 

//... 

foreach (CustomObject myCustomObject in customObjects) 
{ 
    if (anotherListofCustomObjects.Contains(myCustomObject)) 
    { 
     //do stuff 
    } 
} 

問題正在採取永遠處理7000級的對象這樣。

這不是我的代碼 - 我只是試圖提出改進它的選項 - 在我看來,使用字典來獲取按鍵的東西而不是循環遍歷整個集合會更快。

對此提出建議?

+0

perf問題表明您需要查看備用算法或數據結構。正如你自己所說的。 – 2008-12-15 14:05:18

回答

3

那麼,你好像自己回答了嗎?如果您需要對一組數據進行快速查詢,那麼字典可能會比平面列表更好(對於您的數據大小較大)。

你可以,例如,使用對象作爲自己的關鍵 -

Dictionary<CustomObject,CustomObject> ... 

需要注意的是平等的含義取決於上下文。如果你通過原始參考,那很好 - ContainsKey會完成這項工作。如果您有一個不同但相似的平等目的對象,則需要實施您自己的GetHashCode(),Equals(),理想情況下爲IEquatable<CustomObject>。要麼在CustomObject本身,要麼在自定義IEqualityComparer<CustomObject>

+0

使用對象作爲對象的關鍵是沒有別的,然後使用對象本身來找到自己像原始文章中的列表版本。 字典的關鍵字應該小一點,比值項更容易處理。 – 2008-12-15 14:13:41

+0

@BeowulfOF不,事實並非如此。使用對象作爲鍵的速度更快,因爲您可以使用同一個對象(來自另一個列表)來檢查它是否在字典中。 – 2008-12-15 14:18:25

2

確實你的代碼目前是O(n^2),這會很慢。您可以:

  • 用詞典或KeyedCollections代替,這將使其O(n日誌n)的
  • ,如果你能保證該項目以相同的順序,你可以重寫最後一個循環只使用一個索引,這將是爲O(n)
9

除了字典另一種方式是,如果你在.NET 3.5,使用LINQ到對象和Intersect:

foreach(CustomObject c in customObjects.Intersect(anotherListOfCustomObjects)) 
{ 
    // do stuff. 
} 

根據反射器,它使用基於哈希的集合來執行序列的交集。

0

只是一個小除了其他意見。如果您需要將其他客戶列表進行排序,則可以使用SortedList。

1

測試是你的朋友。集合的大小決定了你應該使用的數據結構/算法。我建議你做一些性能基準測試中的下列選項:

  1. 您當前的解決方案
  2. 使用BinarySearch算法在排序列表。
  3. 使用HashSet<CustomObject>

鑑於元素的數量,我懷疑HashSet<CustomObject>是要走的路。

0

Hashset也很好。

new HashSet<CustomObject>().Join() 
相關問題