我有60k项需要根据20k查找列表进行检查。是否有一个集合对象(如List
,HashTable
)提供异常快速的Contains()
方法?或者我必须自己写吗?换句话说,默认的Contains()
方法是扫描每个项目还是使用更好的搜索算法。
foreach (Record item in LargeCollection)
{
if (LookupCollection.Contains(item.Key))
{
// Do something
}
}
注意即可。查找列表已经排序。
答案 0 :(得分:131)
在最常见的情况下,请将System.Collections.Generic.HashSet
视为默认的“包含”主力数据结构,因为评估Contains
需要花费一些时间。
“什么是最快的可搜索集合”的实际答案取决于您的具体数据大小,有序数,散列成本和搜索频率。
答案 1 :(得分:69)
如果您不需要订购,请尝试HashSet<Record>
(.Net 3.5新手)
如果您这样做,请使用List<Record>
并致电BinarySearch
。
答案 2 :(得分:21)
您考虑过List.BinarySearch(item)
吗?
你说你的大集合已经分类了所以这似乎是一个绝佳的机会?哈希肯定是最快的,但这会带来自身的问题,需要更多的存储开销。
答案 3 :(得分:10)
您应该阅读this blog,使用单线程和多线程技术快速测试几种不同类型的集合和方法。
根据搜索结果,列表中的二进制搜索和SortedList是在将某些东西视为&#34;值&#34;时不断奔跑的最佳表现者。
当使用允许&#34;键&#34;的集合时,Dictionary,ConcurrentDictionary,Hashset和HashTables整体表现最佳。
答案 4 :(得分:4)
将两个列表x和y保持排序顺序。
如果x = y,请执行您的操作,如果x&lt; y,如果y 此交点的运行时间与min(size(x),size(y)) 不要运行.Contains()循环,这与x * y成正比,这更糟糕。
答案 5 :(得分:3)
如果可以对项目进行排序,那么有一种更快的方法可以执行此操作,然后对哈希表或b树进行密钥查找。虽然如果你的物品不可分类,你无论如何都无法真正将它们放入b树中。
无论如何,如果对两个列表进行排序排序,那么只需按顺序遍历查找列表。
Walk lookup list
While items in check list <= lookup list item
if check list item = lookup list item do something
Move to next lookup list item
答案 6 :(得分:3)
如果您使用的是.Net 3.5,则可以使用以下方法编写更清晰的代码:
foreach (Record item in LookupCollection.Intersect(LargeCollection))
{
//dostuff
}
我这里没有.Net 3.5,所以这是未经测试的。它依赖于扩展方法。并非LookupCollection.Intersect(LargeCollection)
可能与LargeCollection.Intersect(LookupCollection)
不一样......后者可能要慢得多。
这假定LookupCollection是HashSet
答案 7 :(得分:2)
如果你不担心每个最后一点性能发出吱吱声,那么使用HashSet或二进制搜索的建议是可靠的。您的数据集不够大,99%的时间都会出现问题。
但是,如果这只是成千上万次中的一次,并且性能至关重要(并且使用HashSet /二进制搜索证明是不可接受的),那么您当然可以编写自己的算法,将排序后的列表作为比较进行比较。你去了。每个列表最多走一次,在病理情况下也不会坏(一旦你走这条路线,你可能会发现比较,假设它是一个字符串或其他非整数值,将是真正的费用和那将是下一步的优化。