有一个具有惰性和严格实现的数据结构列表:
Data.Map.Lazy
和 Data.Map.Strict
Data.IntMap.Lazy
和 Data.IntMap.Strict
Data.HashMap.Lazy
和 Data.HashMap.Strict
Data.ByteString.Lazy
和 Data.ByteString.Strict
Data.Text.Lazy
和 Data.Text
这些实现的优势和劣势是什么?在选择特定实现时要遵循哪些规则?
最佳答案
Data.XYMap.Lazy
和 Data.XYMap.Strict
对于
XY
在 {"", "Int", "Hash"}
: *.Strict
变体在将映射到的值放入映射之前强制将其评估为 WHNF。这样做的最大优势是更可预测的空间和时间行为,因为构建巨大的 thunk 要困难得多,尤其是对于表单类型 (
ConstructorN UnboxedValueTypeN
),这是不可能的。缺点 - 我记得在讨论严格或惰性变体是否应该成为默认变体时提出了一些例子,但我不记得有什么特别的事情。
啊,刚刚想起一个用例:可以用
Lazy
打结。变体,这当然是不可能的 Strict
版本!所以如果你做这样的事情:Lazy
.我使用
Strict
默认版本。直到我需要打结或遇到另一个我考虑 Lazy
的用例变种优越,我不知道什么时候会使用它们。Data.(ByteString/Text).Lazy
和 Data.(ByteString/Text).Strict
严格的版本使用一个单一的存储 block 来存储有效负载,这意味着您可以快速随机访问,不仅可以顺序访问,还可以从末尾向后或来回跳转。
惰性版本基本上是严格 block 的头部严格列表,它们的优势在于它们的顺序消耗通常可以在恒定的小内存中完成,如果您需要顺序处理大文件,那就太好了。
对于小(ish)数据,绝对使用
Strict
变体,对于海量数据,Lazy
如果数据是按顺序处理(或多或少)的变体。
关于haskell - 数据结构的惰性与严格实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16296571/