2014-10-29 77 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(); 

    } 
}