2014-10-29 79 views
1

我有一個包含1000000個項目的列表,我需要弄清楚項目是否在裏面,但是通過引用。因此,我不能使用Contains,因爲Contains並不總是按引用匹配(例如,當類型爲string的列表時)。我試過list.Any(x => object.ReferenceEquals),但那太慢了。有一個項目比較參考?

到這裏看看:

for(int i = 0; i < 1000000; i++) 
{ 
    if(does list contains this item anotherList[i]) 
    { 
    list.Add(anotherList[i]); 
    } 
} 

如何執行這個真快?

+1

顯然你的清單太大了。通過將列表中的對象也存儲在HashSet中來加快速度。 – 2014-10-29 13:43:30

回答

1

使用帶有IdendityEqualityComparer的字典獲取字典中的鍵比較以進行參考比較。這種方法與你的主要區別在於你有O(1)查找,而不是從每個項目的整個列表中獲得的O(n)查找。

將下面的代碼放在示例控制檯應用程序項目中;它基本上將主字典分成兩部分。

public class IdentityEqualityComparer<T> : IEqualityComparer<T> where T : class 
{ 
    public int GetHashCode(T value) 
    { 
     return RuntimeHelpers.GetHashCode(value); 
    } 

    public bool Equals(T left, T right) 
    { 
     return left == right; // Reference identity comparison 
    } 
} 

public class RefKeyType 
{ 
    public int ID { get; set; } 
} 

class Program 
{ 
    public static void Main() 
    { 
     var refDictionary = new Dictionary<RefKeyType, int>(1000000, new IdentityEqualityComparer<RefKeyType>()); 

     var testDictionary = new Dictionary<RefKeyType, int>(1000000, new IdentityEqualityComparer<RefKeyType>()); 

     var store = new Dictionary<RefKeyType, int>(1000000); 

     for (var i = 0; i < 1000000; i++) 
     { 
      var key = new RefKeyType() {ID = i}; 

      refDictionary[key] = i; 

      //Load the test dictionary if I is divisible by 2 
      if (i%2 == 0) 
      { 
       testDictionary[key] = i; 
      } 
     } 

     foreach (var key in refDictionary.Keys) 
     { 
      int val; 
      if (!testDictionary.TryGetValue(key, out val)) 
      { 
       store[key] = val; 
      } 
     } 

     Console.WriteLine("Master dictionary has " + refDictionary.Count); 
     Console.WriteLine("Test dictionary has " + testDictionary.Count); 
     Console.WriteLine("Store dictionary has " + store.Count); 
     Console.WriteLine("Press any key to exit."); 
     Console.ReadKey(); 

    } 
}