scala - 是否存在或将存在扩展 Seq 的 Scala 集合,其迭代速度比 Array 更快?
问题描述
根据我测试和阅读的内容,在通过、和Array
进行随机访问或迭代时,它是最快的集合,但它们是可变的,不像,不幸的是,它不如.foreach
while
tailrec
Vector
Array
我仍然坚持使用 Scala 2.11,但我最近发现 Scala 2.13 已经发生了变化。是否有希望存在或将存在一个Array
在随机访问方面超越的不可变集合?
这是 上的欧几里得距离的一个例子Array[Double]
,它在 Seq 后代上的工作方式完全相同。
final def euclidean(v1: Array[Double], v2: Array[Double]): Double = {
@annotation.tailrec
def go(d: Double, i: Int): Double = {
if(i < v1.size) {
val toPow2 = v1(i) - v2(i)
go(d + toPow2 * toPow2, i + 1)
}
else d
}
sqrt(go(0D, 0))
}
解决方案
总的来说,我认为Array
在 JVM 中的随机访问方面是不可能超越的。由于数组元素的大小相等,并且它们在内存中按顺序定位,因此可以使用给定的索引在恒定时间内快速计算出元素的位置。更重要的是,这会导致良好的缓存局部性。
在最好的情况下,集合可以具有与数组相当的随机访问性能。查看提到的 scala 2.11 源代码ArraySeq
,它说:
这意味着 * 原始类型的元素被装箱。
https://github.com/scala/scala/blob/2.11.x/src/library/scala/collection/mutable/ArraySeq.scala#L19
这很可能解释了观察到的 10% 的性能下降。数组具有toSeq
作为 a 实现的方法,WrappedArray
并且每种原始类型都有专门的实现,我认为这是 scala 2.11 中用于包装数组的性能最高的集合https://github.com/scala/scala/blob/2.11.x/ src/library/scala/collection/mutable/WrappedArray.scala#L173。
推荐阅读
- hyperledger-fabric - 对等背书策略不起作用的超级账本结构
- codeigniter - 自动加载 form_validation 库
- python - 如何调整我的代码以适应 Django 升级?
- python - 如何在上一行仍在运行时跳转到另一行 python 代码
- sql - 数据工厂 v2 过滤时间小时窗口
- algorithm - 从输出重构编码器的输入
- css - css占位符选择器仅不适用于颜色
- opengl - glUseProgram 会改变 VAO 和/或 VBO 状态吗?
- .net - 已尝试使用数据扩展名“ORACLE”错误
- javascript - 如何使用 foreach 捕获输入元素