【发布时间】:2013-12-30 22:44:09
【问题描述】:
我看到了很多关于 Scala 集合的问题,但无法做出决定。 这个question 是迄今为止最有用的。
我认为问题的核心是双重的: 1)对于这个用例,哪些是最好的集合? 2) 有哪些推荐的使用方式?
详情:
我正在实现一个迭代集合中所有元素的算法 搜索符合某个标准的那个。 搜索后,下一步是使用新标准再次搜索,但在可能性中没有选择的元素。 这个想法是创建一个序列,其中包含按标准排序的所有原始元素(在每次新选择时都会改变)。 原始序列实际上不需要排序,但可以有重复(算法一次只会选择一个)。 带有小整数序列的示例(只是为了简化):
object Foo extends App {
def f(already_selected: Seq[Int])(element: Int): Double =
// something more complex happens here,
// specially something take takes 'already_selected' into account
math.sqrt(element)
//call to the algorithm
val (result, ti) = Tempo.time(recur(Seq.fill(9900)(Random.nextInt), Seq()))
println("ti = " + ti)
//algorithm
def recur(collection: Seq[Int], already_selected: Seq[Int]): (Seq[Int], Seq[Int]) =
if (collection.isEmpty) (Seq(), already_selected)
else {
val selected = collection maxBy f(already_selected)
val rest = collection diff Seq(selected) //this part doesn't seem to be efficient
recur(rest, selected +: already_selected)
}
}
object Tempo {
def time[T](f: => T): (T, Double) = {
val s = System.currentTimeMillis
(f, (System.currentTimeMillis - s) / 1000d)
}
}
【问题讨论】:
-
据我了解 recur 不会终止
-
完整的可编译代码添加到问题
-
在我的测试中,Vector 和 Array 比 List 和 Seq 慢 15%。
-
@davips Seq 不是一个特定的类,它的默认实现是 List。另一方面,IndexedSeq 默认实现是 Vector。还要注意有一堆东西which complicate benchmarking of JVM code。您似乎没有考虑它们。
-
我认为
diff在这里并不重要,因为maxBy是一个 O(n) 操作(可能更多)。在修改旧的Seq时为了结构共享的好处,可以考虑zipWithIndex,这个解决方案:stackoverflow.com/questions/12864505/…