Когда отвечая на вопрос с предложением использовать GADT, в комментариях возникло несколько вопросов относительно производительности. Вопрос касался класса типов PlotValue
:
class PlotValue a where
value :: a -> Double
и мой ответ предложил использовать GADT Input
:
data Input where
Input :: (PlotValue a, PlotValue b) => Maybe a -> Maybe b -> Input
но подробности, я полагаю, несущественны.
Меня интересуют два аспекта производительности:
Время: есть ли какие-либо затраты во время выполнения, связанные с сопоставлением с шаблоном, например
case x of
Input (Just a) (Just b) -> value a * value b
_ -> 0.0
сверх обычных затрат, соответствующих двум значениям Maybe
?
Пространство. Сколько дополнительных ресурсов хранения несет значение типа Input
? Я предполагаю, что он содержит два словаря PlotValue
для каждого значения типа Input
(«указатель» каждый?), а это означает, что [Input]
будет гораздо более неэффективным с точки зрения использования памяти, чем использование (Just Double, Just Double)
или, что еще лучше, (# #Double, #Double #)
- если вы сохраняете результаты value
в обычном или неупакованном кортеже.
Итак, хотя мне нравится выразительность, которую дают мне GADT, я никогда особо не задумывался об аспектах производительности. Может ли кто-нибудь рассказать мне больше об этом (и о любых других скрытых расходах, о которых я мог не знать)?