快速问答。我目前正在设计一些数据库查询,以提取相当大的数据集到内存中,例如大约10k-100k记录。
到目前为止,我一直在测试将这些结果集加载到scala.collection.immutable.Seq中,并发现构建集合似乎需要相当长的时间。然而,如果我更改为Vector或List,则写入内存需要几分之一秒的时间。
因此,我的问题是,为什么Seq在这种情况下会如此缓慢?如果是这样,在什么情况下使用Seq比使用Vector更合适?
谢谢
发布于 2013-06-13 21:05:11
如果您发布相关的代码片段以及在序列上调用哪些操作,这将有所帮助-- immutable.Seq使用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操作符::只创建一个节点并将其链接到列表的其余部分,这对于不可变数据结构来说是最快的。否则,如果您在末尾添加,并且坚持不可变性,那么您应该使用Vector (或者即将发布的Conc列表!)。
如果您想要验证这些声明,请参阅此link,其中使用ScalaMeter比较了两种操作的性能--列表在添加到开头时比向量快8倍。
但是,最合适的数据结构应该是ArrayBuffer或VectorBuilder。这些是动态调整大小的可变数据结构,如果您使用+=构建它们,您将获得合理的性能。这是假设您没有存储原语。
https://stackoverflow.com/questions/17087650
复制相似问题