По состоянию на 2017 год предыдущие ответы, похоже, устарели.Я провел несколько тестов (список из 10 миллионов Ints, первое совпадение примерно посередине, Scala 2.12.3, Java 1.8.0, 1,8 ГГц Intel Core i5).Если не указано иное, list
и map
имеют следующие типы:
list: scala.collection.immutable.List
map: A => Option[B]
Просто позвоните map
в списке: ~ 1000 мс
list.map(map).find(_.isDefined).flatten
Первый вызов toStream
в списке: ~ 1200 мс
list.toStream.map(map).find(_.isDefined).flatten
вызов toStream.flatMap
в списке: ~ 450 мс
list.toStream.flatMap(map(_).toList).headOption
вызов flatMap
в списке: ~ 100 мс
list.flatMap(map(_).toList).headOption
Первый вызов iterator
в списке: ~ 35 мс
list.iterator.map(map).find(_.isDefined).flatten
Рекурсивная функция find()
: ~ 25 мс
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 мс
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 мс
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 мс
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
будут показывать другую производительность - большинство будет хуже.)