快速提问。我目前正在设计一些数据库查询以将相当大但不是海量的数据集提取到内存中,例如大约 10k-100k 记录。
到目前为止,我一直在测试将这些结果集加载到 scala.collection.immutable.Seq 中,并发现构建集合似乎需要很长时间。而如果我更改为 Vector 或 List 写入内存需要几分之一秒。
因此,我的问题是为什么在这种情况下 Seq 这么慢?如果是这样,在什么情况下使用 Seq 比 Vector 更合适?
谢谢
快速提问。我目前正在设计一些数据库查询以将相当大但不是海量的数据集提取到内存中,例如大约 10k-100k 记录。
到目前为止,我一直在测试将这些结果集加载到 scala.collection.immutable.Seq 中,并发现构建集合似乎需要很长时间。而如果我更改为 Vector 或 List 写入内存需要几分之一秒。
因此,我的问题是为什么在这种情况下 Seq 这么慢?如果是这样,在什么情况下使用 Seq 比 Vector 更合适?
谢谢
如果您发布相关的片段以及您在序列上调用哪些操作会有所帮助 -immutable.Seq
使用 a 表示List
(请参阅https://github.com/scala/scala/blob/v2.10.2/src/library/scala /collection/immutable/Seq.scala#L42)。我的猜测是你一直在使用:+
,immutable.Seq
它在引擎盖下通过复制它附加到列表的末尾(可能会给你二次整体性能),当你切换到immutable.List
直接使用时,你一直在附加到开始使用::
(给你线性性能)。
因为Seq
它只是一个List
底层,你应该在附加到序列的开头时使用它—— cons 运算符::
只创建一个节点并将其链接到列表的其余部分,这是它可以达到的最快速度它涉及不可变的数据结构。否则,如果你添加到最后,并且你坚持不变性,你应该使用 a Vector
(或即将到来的Conc
列表!)。
如果您想验证这些声明,请参阅此链接,其中使用 ScalaMeter 比较了两个操作的性能——当您添加到开头时,列表比向量快 8 倍。
但是,最合适的数据结构应该是 anArrayBuffer
或 a VectorBuilder
。这些是动态调整大小的可变数据结构,如果您使用它们构建它们,+=
您将获得合理的性能。这是假设您没有存储原语。