Ответ 1
Это зависит от варианта использования. Для функций, которые у вас есть, ожидалось, что перечисление будет работать лучше. В принципе, три конструктора D
становятся Int
соответственно. Int#
, когда анализ строгости позволяет это, и GHC знает, что он статически проверяет, что аргумент может иметь только одно из трех значений 0#, 1#, 2#
, поэтому ему не нужно вставлять код обработки ошибок для f
. Для E
статическая гарантия только одного из трех возможных значений не задана, поэтому ей необходимо добавить код обработки ошибок для g
, что значительно замедляет работу. Если вы измените определение g
так, чтобы последний случай стал
E _ -> 3535#
разница полностью или почти полностью исчезает (я получаю 1% - 2% лучший тест для f
, но я не сделал достаточного тестирования, чтобы убедиться, что это реальная разница или артефакт бенчмаркинга).
Но это не тот случай, о котором говорит страница wiki. Речь идет о распаковке конструкторов в другие конструкторы, когда тип является компонентом других данных, например
data FooD = FD !D !D !D
data FooE = FE !E !E !E
Затем, если скомпилировано с -funbox-strict-fields
, три Int#
могут быть распакованы в конструктор FooE
, поэтому вы в основном получите эквивалент
struct FooE {
long x, y, z;
};
в то время как поля FooD
имеют тип multi-constructor D
и не могут быть распакованы в конструктор FD
(1) так что это в основном даст вам
struct FooD {
long *px, *py, *pz;
}
Это, очевидно, может оказать значительное влияние.
Я не уверен в случае аргументов функции с одним конструктором. Это имеет очевидные преимущества для типов с содержащимися данными, такими как кортежи, но я не вижу, как это применимо к простым перечислениям, где у вас просто есть case
и разделение рабочего и обертка не имеет смысла (для меня).
Во всяком случае, преобразование рабочего/обертки не является чем-то вроде одного конструктора, специализация конструктора может принести одинаковое преимущество типам с несколькими конструкторами. (Для того, сколько конструкторов будет создано, зависит от значения -fspec-constr-count
.)
(1) Это могло измениться, но я сомневаюсь. Я не проверял его, так что, возможно, страница устарела.