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