IntおよびFloatフィールドに大きな計算を格納していない限り、かなりのオーバーヘッドは、サンクに蓄積される多くの簡単な計算から増やすことができます。たとえば、データ型の怠惰なFloatフィールドに1を繰り返し追加すると、実際にフィールドを強制計算して計算するまで、より多くのメモリが消費されます。
しばしば、高価な計算をフィールドに保存したいとします。しかし、あらかじめそのようなことをしていないことが分かっている場合は、フィールドを厳密にマークして、手動でseq
を追加しなくても、効率を上げる必要はありません。フラグが与えられたとき、追加のボーナスとして
は、
-funbox-strict-fields
GHCは、直接、彼らが常に評価される知っているので可能であるデータ・タイプ自体に厳密なフィールドのデータ型のを解凍し、従ってないサンクをしなければなりません割り当てられる。この場合、Bar値は、データを含むサンクに対する2つのポインタを含むのではなく、メモリ内のBar値の中にIntおよびFloatを直接含む機械語を含むことになる。
怠惰は非常に有用なことですが、時には、ちょうど途中に入り込んで計算を妨げます。特に、常に見られる(したがって強制される)小さなフィールドや、非常に高価な計算。厳密なフィールドは、データ型のすべての用途を変更することなく、これらの問題を克服するのに役立ちます。
これはレイジーフィールドよりも一般的であるかどうかは、読んでいるコードのタイプによって異なります。機能的なツリー構造が怠惰から大きく恩恵を受けるため、厳密なフィールドを広く使用することはありません。
あなたが中置演算のためのコンストラクタを持つASTを持っているとしましょう:
data Exp = Infix Op Exp Exp
| ...
data Op = Add | Subtract | Multiply | Divide
そのようにポリシーを適用すると全体ASTが評価されていることを意味するだろうとあなたは、Exp
フィールドが厳密にしたいではないでしょうあなたが怠惰から恩恵を受けたいと思っているものではない、トップレベルのノードを見るたびに。しかし、Op
フィールドには、後で延期したい高価な計算は含まれません。また、実際に深くネストされた解析ツリーがある場合は、中断演算子ごとのサンクのオーバーヘッドが高価になる可能性があります。したがって、インフィクスコンストラクタでは、Op
フィールドを厳密にしたいが、2つのフィールドは怠惰なままにしておきたい。
単一コンストラクタタイプのみをアンパックすることができます。
ASTのように厳密にする必要はありませんか? – Lanbo
私はASTを例にしていくつかの精緻化をして私の答えを広げました。 – ehird