截至 2017 年,之前的答案似乎已经过时。我运行了一些基准测试(1000 万个 Ints 列表,第一个匹配大致在中间,Scala 2.12.3、Java 1.8.0、1.8 GHz Intel Core i5)。除非另有说明,否则list
有map
以下几种:
list: scala.collection.immutable.List
map: A => Option[B]
只需调用map
列表:~1000 ms
list.map(map).find(_.isDefined).flatten
列表中的第一个调用toStream
:~1200 ms
list.toStream.map(map).find(_.isDefined).flatten
列表调用toStream.flatMap
:~450 ms
list.toStream.flatMap(map(_).toList).headOption
在列表中调用flatMap
:~100 ms
list.flatMap(map(_).toList).headOption
列表中的第一个调用iterator
:~35 ms
list.iterator.map(map).find(_.isDefined).flatten
递归函数find()
:~25 ms
def find[A,B](list: scala.collection.immutable.List[A], map: A => Option[B]) : Option[B] = {
list match {
case Nil => None
case head::tail => map(head) match {
case None => find(tail, map)
case result @ Some(_) => result
}
}
}
迭代函数find()
:~25 ms
def find[A,B](list: scala.collection.immutable.List[A], map: A => Option[B]) : Option[B] = {
for (elem <- list) {
val result = map(elem)
if (result.isDefined) return result
}
return None
}
您可以通过使用 Java 而不是 Scala 集合和功能较少的样式来进一步加快速度。
循环索引java.util.ArrayList
:~15 ms
def find[A,B](list: java.util.ArrayList[A], map: A => Option[B]) : Option[B] = {
var i = 0
while (i < list.size()) {
val result = map(list.get(i))
if (result.isDefined) return result
i += 1
}
return None
}
java.util.ArrayList
使用函数返回null
而不是循环遍历索引None
:~10 ms
def find[A,B](list: java.util.ArrayList[A], map: A => B) : Option[B] = {
var i = 0
while (i < list.size()) {
val result = map(list.get(i))
if (result != null) return Some(result)
i += 1
}
return None
}
(当然,通常将参数类型声明为java.util.List
,而不是java.util.ArrayList
。我在这里选择后者,因为它是我用于基准测试的类。其他实现java.util.List
将显示不同的性能 - 大多数会更糟。)