Haskell:使用严格性的指南
Posted
技术标签:
【中文标题】Haskell:使用严格性的指南【英文标题】:Haskell: Guidelines for using Strictness 【发布时间】:2014-02-12 06:59:24 【问题描述】:在 Haskell 中何时使用严格性是否有任何推荐指南?
例如,我正在查看 tagsoup 库。他们的数据结构之一定义如下:
data Tag str
= TagOpen str [Attribute str]
| TagClose str
| TagText str
| TagComment str
| TagWarning str
| TagPosition !Row !Column
type Row = Int
type Column = Int
那么,他们究竟基于什么因素决定 TagPosition
应该严格?对此有什么推荐的指导方针吗?
【问题讨论】:
一个列表是非严格的并且代表一个流(根据需要评估它的元素是有意义的)。一个 Int 代表一个数字。懒惰地评估它仍然有意义(例如,它可能代表您并不真正需要的流的长度)。简而言之:这取决于应用程序。 @d8d0d65b3f7cf42 实际上,如果我们谈论像 Int 这样的东西,会如果你从不使用这个值,那么偷懒会更快吗?数值运算非常快,我不确定这与生成 thunk 的速度相比如何。这还没有考虑到内存成本。 @DavidYoung 正如我所说,这不太可能。但如果你把它当作一个挑战,我相信有可能想出一个更快的场景。总是有可能有一个Int
字段,您在该字段上的计算量很少,但计算成本极高,而且您很少需要。那么懒惰的Int
会更快。
【参考方案1】:
对于简单的非结构化数据类型,例如Int
或Double
,将它们转换为严格字段通常是一个不错的默认设置。这使得他们的空间消耗非常可预测(并且恒定)。虽然执行不必要的计算可能会导致性能下降,但这通常不太可能。例如,跟踪位置通常非常简单且成本低廉,因此在性能方面没有什么可害怕的,而且具有可预测的空间行为更为重要。
使简单类型严格的另一个优点是它们通常可以解包,即直接存储在构造函数中,而不是通过额外的间接(有编译指示或编译器标志)。对于小型类型,这通常是一个优势。
对于列表或树等结构化数据类型,情况要复杂得多。一个简单的!
在这里很少有帮助,因为它只会强制执行 WHNF。评估的列表或树在空间方面也很容易比未评估的 thunk 更昂贵。然而,有时对这些数据进行严格也是有意义的。在这种情况下,您通常会使用一个函数(所谓的智能构造函数)包装构造函数,该函数通过在适当的位置调用deepseq
来建立严格不变量。
【讨论】:
以上是关于Haskell:使用严格性的指南的主要内容,如果未能解决你的问题,请参考以下文章