懒惰与严格的数据结构实现

时间:2013-04-30 09:32:13

标签: haskell containers

有一个具有惰性和严格实现的数据结构列表:

  • Data.Map.LazyData.Map.Strict
  • Data.IntMap.LazyData.IntMap.Strict
  • Data.HashMap.LazyData.HashMap.Strict
  • Data.ByteString.LazyData.ByteString.Strict
  • Data.Text.LazyData.Text

这些实施的优点和缺点是什么?选择特定实施时应遵循哪些规则?

2 个答案:

答案 0 :(得分:25)

  • Data.XYMap.LazyData.XYMap.Strict
XY{"", "Int", "Hash"}

*.Strict变体强制将映射到的值评估为WHNF,然后再将它们放入地图中。

这样做的最大优点是更可预测的空间和时间行为,因为构建巨大的thunk非常困难,特别是对于表单类型(ConstructorN UnboxedValueTypeN),这是不可能的。

缺点 - 我记得在讨论严格或懒惰变体是否应该成为默认变量时会出现一些例子,但我不记得任何特别的事情。

啊,只记得一个用例:一个人可以用Lazy变体打结,这对于Strict版本来说当然是不可能的!所以如果你这样做:Lazy

我默认使用Strict版本。直到我需要打结或遇到另一个用例,我认为Lazy变体更优越,我不知道何时会使用它们。

  • Data.(ByteString/Text).LazyData.(ByteString/Text).Strict

严格版本为有效载荷使用一个单片存储块,这意味着您可以快速随机访问,不仅可以顺序访问,还可以从末尾向后或者来回跳转。

懒惰版本基本上是严格的严格块列表,它们的优势在于它们的顺序消耗通常可以在恒定的小内存中完成,如果您需要按顺序处理大型文件,这很好。

对于小(ish)数据,绝对使用Strict变体,对于大数据Lazy变体,如果数据是按顺序处理(或多或少)。

答案 1 :(得分:22)

  

这些实施的优点和缺点是什么?选择特定实施时应遵循哪些规则?

该类型的严格性或懒惰导致特定操作或使用模式的不同复杂性。

没有严格或快速的规则 - 相反,您可能会将它们视为完全不同的数据类型。

如果你坚持一些指导原则:

  • 数据大于内存的延迟结构
  • 不经常使用的数据的懒惰结构或当您使用大型结构的一小部分时

然后:

  • 严格的结构,如果你做了很多更新
  • 小型原子数据的严格结构