Если вы не храните большие вычисления в полях Int и Float, значительные накладные расходы могут возникнуть из-за большого количества простых вычислений, создаваемых в виде блоков.Например, если вы неоднократно добавляете 1 к ленивому полю Float в типе данных, он будет использовать все больше и больше памяти, пока вы фактически не заполните поле, вычисляя его.
Часто вы хотите хранить в дорогихвычисления в поле.Но если вы знаете, что не будете делать ничего подобного раньше, вы можете пометить поле строго и избегать необходимости вручную добавлять seq
везде, чтобы получить желаемую эффективность.
В качестве дополнительногоБонус, когда ему присваивается флаг -funbox-strict-fields
, GHC распаковывает строгие поля 1 типов данных непосредственно в сам тип данных, что возможно, поскольку он знает, что они всегда будут оцениваться, и, таким образом, не требуется никакого thunkвыделено;в этом случае значение Bar будет содержать машинные слова, содержащие Int и Float, непосредственно внутри значения Bar в памяти, а не два указателя на thunks, которые содержат данные.
Лень - очень полезная вещь,но иногда это мешает и мешает вычислениям, особенно для небольших полей, которые всегда просматриваются (и, следовательно, принудительно), или которые часто изменяются, но никогда не требуют очень дорогих вычислений.Строгие поля помогают преодолеть эти проблемы без необходимости изменять все типы данных.
Зависит ли это от более ленивых полей или нет, зависит от типа кода, который вы читаете;маловероятно, что какие-либо функциональные древовидные структуры широко используют строгие поля, например, потому что они очень выигрывают от лени.
Допустим, у вас есть AST с конструктором для операций с инфиксами:
data Exp = Infix Op Exp Exp
| ...
data Op = Add | Subtract | Multiply | Divide
Вы не хотели бы ужесточать поля Exp
, так как применение подобной политики будет означать, что весь AST оценивается всякий раз, когда вы смотрите на узел верхнего уровня, что явно не то, что вы хотитеизвлечь выгоду из лени.Однако поле Op
никогда не будет содержать дорогостоящих вычислений, которые вы хотите отложить на более позднюю дату, и издержки оператора thunk per infix могут быть дорогими, если у вас действительно глубоко вложенные деревья разбора.Таким образом, для конструктора инфиксов вы должны сделать поле Op
строгим, но оставить два поля Exp
ленивыми.
1 Распаковать можно только типы с одним конструктором.