Performance implications of using GADTs
-
11-11-2019 - |
Question
When answering a question with a suggestion to use GADTs, some questions with regards to performance came up in the comments. The question involved a typeclass PlotValue
:
class PlotValue a where
value :: a -> Double
and my answer suggested using a GADT Input
:
data Input where
Input :: (PlotValue a, PlotValue b) => Maybe a -> Maybe b -> Input
but the details are, I suppose, immaterial.
I'm wondering about two aspects of performance:
Time: Are there any runtime costs incurred by a pattern match like
case x of
Input (Just a) (Just b) -> value a * value b
_ -> 0.0
over and above the normal costs matching two Maybe
values?
Space:
How much storage overhead does a value of type Input
carry? My guess is that it carries the two PlotValue
dictionaries around for each and every value of type Input
(a 'pointer' each?), meaning that a [Input]
will be much more inefficient in terms of memory use than using (Just Double, Just Double)
or, better yet, (# #Double, #Double #)
- if you store the results of value
in a normal or unpacked tuple.
So, while I love the expressiveness GADTs give me, I've never thought about the performance aspects much. Can anyone tell me more about this (and any other hidden costs I might not be aware of)?
No correct solution