对于所有可能的操作,显然Seq
渐近地执行与[]
相同或更好的操作。但由于它的结构比列表更复杂,对于小尺寸,它的恒定开销可能会使它变慢。我想知道多少,特别是:
<|
与:
相比要慢多少?Seq
相比折叠/遍历[]
的速度有多慢(不包括折叠/遍历功能的成本)?\xs x -> xs ++ [x]
变得比|>
慢的大小(大约)是多少?++
变得比><
慢的大小(大约)是多少?viewl
和结果模式匹配的成本是多少?n
- 元素列表相比,Seq
- 元素n
占用了多少内存? (不计算元素占用的内存,只计算结构。)我知道这很难衡量,因为我们用Seq
谈论摊销的复杂性,但我想知道至少一些粗略的数字。
答案 0 :(得分:13)
这应该是一个开始 - http://www.haskell.org/haskellwiki/Performance#Data.Sequence_vs._lists
序列使用的空间是等效列表的5/6和4/3倍(假设每个节点有一个字的开销,如GHC中所示)。如果仅使用deque操作,则空间使用将接近范围的下端,因为所有内部节点都将是三元组。大量使用拆分和追加将导致序列使用与列表大致相同的空间。详细说明:
对于头部(cons和head)的操作,List是一个非平凡的常数因子,使其成为类似堆栈和类似流的访问模式的更有效选择。对于每个其他访问模式,Data.Sequence都更快,例如队列和随机访问。
答案 1 :(得分:1)
我还有一个具体的结果可以添加到上面的答案中。我正在解决一个Langevin方程。我使用了List和Data.Sequence。在此解决方案中,列表/序列后面的大量插入正在进行中。
总而言之,我没有看到速度有任何改善,实际上性能因序列而恶化。此外,使用Data.Sequence,我需要增加可用于Haskell RTS的内存。
因为我绝对不是优化的权威;我在下面发布了这两个案例。我很高兴知道这是否可以改善。两个代码都使用-O2
标志进行编译。