SCALA:使用“.contains()”或“.exists()”时哪种情况下哪种数据结构是最佳的?

时间:2013-05-08 14:22:33

标签: performance scala data-structures scala-collections

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

我问,因为我来自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

直观地说,我认为向量应该是随机检查最快的,如果知道检查的值在列表的开头并且有大量数据,则列表将是最快的。但是,我们非常欢迎确认或更正。另外,请随意扩展到其他数据结构。

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

2 个答案:

答案 0 :(得分:17)

SetMap(使用默认哈希表实现)到目前为止contains最快,因为它们计算哈希值并立即跳转到正确的位置。例如,如果要从一千个列表中查找任意字符串,则contains上的containsListVector上的Array快约100倍或exists

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

答案 1 :(得分:1)

如果您想广泛使用contains,则应使用Set(或Map)。

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