20

我想知道在哪些情况下哪些数据结构最适合使用“包含”或“存在”检查。

我问是因为我来自 Python 背景,并且习惯于if x in something:对所有事情使用表达式。例如,哪些表达式的计算速度最快:

val m = Map(1 -> 1, 2 -> 2, 3 -> 3, 4 -> 4)
                                          //> m  : scala.collection.immutable.Map[Int,Int] = Map(1 -> 1, 2 -> 2, 3 -> 3, 4
                                          //|  -> 4)
val l = List(1,2,3,4)                     //> l  : List[Int] = List(1, 2, 3, 4)
val v = Vector(1,2,3,4)                   //> v  : scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 4)

m.exists(_._1 == 3)                       //> res0: Boolean = true
m.contains(3)                             //> res1: Boolean = true
l.exists(_ == 3)                          //> res2: Boolean = true
l.contains(3)                             //> res3: Boolean = true
v.exists(_ == 3)                          //> res4: Boolean = true
v.contains(3)                             //> res5: Boolean = true

直观地说,我会假设向量应该是最快的随机检查,如果知道检查的值在列表的开头并且有很多数据,那么列表将是最快的。但是,非常欢迎确认或更正。此外,请随时扩展到其他数据结构。

注意:如果您觉得这个问题太模糊,请告诉我,因为我不确定我的措辞是否正确。

4

2 回答 2

20

SetMap(使用默认哈希表实现)是迄今为止最快的,contains因为它们计算哈希值并立即跳转到正确的位置。例如,如果您想从一千个列表中查找任意字符串,则containson a set 比containson Listor Vectoror快约 100 倍Array

使用exists,您真的只关心集合的遍历速度——无论如何您都必须遍历所有内容。在那里,List通常是冠军(除非你想手动遍历一个数组),但只Set​​有等等通常特别糟糕(例如exists,当每个有 1000 个元素时List,on 比 on 快约 8 倍)。Set其他的在大约 2.5 倍以内List(通常是 1.5 倍,但Vector有一个底层的树结构,遍历的速度不是那么快)。

于 2013-05-08T16:39:30.387 回答
1

如果你想contains广泛使用,你应该使用 a Set(或 a Map)。

AFAIK 没有实现高效(即比 O(n) 更快)的数据结构,exists因为您传入的闭包甚至可能与内部元素无关。

于 2013-05-08T15:35:20.850 回答