Scala中Seq的不同实现之间的转换

时间:2013-08-28 09:28:09

标签: performance scala sequence

根据我的阅读,在定义序列时,应优先使用通用Seq,而不是ListVector等特定实现。

虽然我的代码的一部分当一个序列主要用于完全遍历(映射,过滤等)和我的代码的某些部分,其中相同的序列将用于索引操作(indexOf,lastIndexWhere)。 / p>

在第一种情况下,我认为最好使用LinearSeq(实现是List)而在第二种情况下最好使用IndexedSeq(实现是{{1 }})。

我的问题是:我是否需要在代码中明确调用转换方法VectortoList,还是以智能方式完成转换?如果我使用这些转化,那么在toIndexedSeqIndexedSeq之间往返时,这会对性能造成不利影响吗?

提前致谢

2 个答案:

答案 0 :(得分:1)

Vector几乎总是胜过List。除非您的算法仅使用::headtail,否则Vector将比List更快。 使用List更多是关于算法的概念性问题(数据是堆栈结构的,只访问头/尾,只通过预先添加元素,使用模式匹配(可以与Vector一起使用,对List))使用它感觉更自然。

您可能需要查看Why should I use vector in scala

现在要比较一些不错的数字(显然不是'真正的'基准,但是呃):

val l = List.range(1,1000000)
val a = Vector.range(1,1000000)

import System.{currentTimeMillis=> milli}

val startList = milli
l.map(_*2).map(_+2).filter(_%2 == 0)
println(s"time for list map/filter operations : ${milli - startList}")

val startVector = milli
a.map(_*2).map(_+2).filter(_%2 == 0)
println(s"time for vector map/filter operations : ${milli - startVector}")

输出:

time for list map/filter operations : 1214  
time for vector map/filter operations : 364

编辑: 刚刚意识到这实际上并没有回答你的问题。据我所知,你必须自己调用toList / toVector。至于表演,这取决于你的顺序,但除非你一直来回走,否则不应该是一个问题。

再次,不是一个严肃的基准,但是:

val startConvToList = milli
a.toList
println(s"time for conversion to List: ${milli - startConvToList}")

val startConvToVector = milli
l.toVector
println(s"time for conversion to Vector: ${milli - startConvToVector}")

输出:

time for conversion to List: 48
time for conversion to Vector: 18

答案 1 :(得分:0)

我为indexOf做了同样的事情,而Vector也是更高效的

val l = List.range(1,1000000)
val a = Vector.range(1,1000000)

import System.{currentTimeMillis=> milli}

val startList = milli
l.indexOf(500000)
println("time for list index operation : " + (milli - startList))

val startVector = milli
a.indexOf(500000)
println("time for vector index operation : " + (milli - startVector))

输出:

time for list index operation : 36
time for vector index operation : 33

所以我想我应该在内部实现中一直使用Vector,但是当我按照此处的指定构建接口时我必须使用Seq: Difference between a Seq and a List in Scala