Data.Sequence.Seq与[]相比有多快?

时间:2013-02-10 14:12:49

标签: performance list haskell finger-tree

对于所有可能的操作,显然Seq渐近地执行与[]相同或更好的操作。但由于它的结构比列表更复杂,对于小尺寸,它的恒定开销可能会使它变慢。我想知道多少,特别是:

  1. <|:相比要慢多少?
  2. 与折叠/遍历Seq相比折叠/遍历[]的速度有多慢(不包括折叠/遍历功能的成本)?
  3. \xs x -> xs ++ [x]变得比|>慢的大小(大约)是多少?
  4. ++变得比><慢的大小(大约)是多少?
  5. 与列表上的模式匹配相比,调用viewl和结果模式匹配的成本是多少?
  6. n - 元素列表相比,Seq - 元素n占用了多少内存? (不计算元素占用的内存,只计算结构。)
  7. 我知道这很难衡量,因为我们用Seq谈论摊销的复杂性,但我想知道至少一些粗略的数字。

2 个答案:

答案 0 :(得分:13)

这应该是一个开始 - http://www.haskell.org/haskellwiki/Performance#Data.Sequence_vs._lists

序列使用的空间是等效列表的5/6和4/3倍(假设每个节点有一个字的开销,如GHC中所示)。如果仅使用deque操作,则空间使用将接近范围的下端,因为所有内部节点都将是三元组。大量使用拆分和追加将导致序列使用与列表大致相同的空间。详细说明:

  • 长度为n的列表由n个cons节点组成,每个节点占用3个字。
  • 长度为n的序列具有大约n /(k-1)个节点,其中k是内部节点(每个2或3)的平均值。每个节点都有一个指针,大小和开销,以及每个元素的指针,即n(3 /(k-1)+ 1)个字。

对于头部(cons和head)的操作,List是一个非平凡的常数因子,使其成为类似堆栈和类似流的访问模式的更有效选择。对于每个其他访问模式,Data.Sequence都更快,例如队列和随机访问。

答案 1 :(得分:1)

我还有一个具体的结果可以添加到上面的答案中。我正在解决一个Langevin方程。我使用了List和Data.Sequence。在此解决方案中,列表/序列后面的大量插入正在进行中。

总而言之,我没有看到速度有任何改善,实际上性能因序列而恶化。此外,使用Data.Sequence,我需要增加可用于Haskell RTS的内存。

因为我绝对不是优化的权威;我在下面发布了这两个案例。我很高兴知道这是否可以改善。两个代码都使用-O2标志进行编译。

  1. Solution with List,大约需要13.01秒
  2. Solution with Data.Sequence,大约需要15.13秒