Memory footprint of existentially quantified types and related optimization techniques
haskell, memory, optimization
Solution
The ghc-datasize package may be of help here:
{-# LANGUAGE RankNTypes, GADTs #-}
import GHC.DataSize
data Node = forall a. Show a => Node a
main = do
s <- closureSize $ Node 0
print s -- 24 bytes on my 64-bit system
So, it seems that `Node` takes one extra word compared to the plain unary data constructor, presumably because of the `Show` class dictionary pointer. Also, I tried adding more class constraints to `Node`, and each of them takes one extra word of space.
I don't know for sure whether it is possible to magic away the dictionary pointer in specific circumstances. I think it isn't possible if you'd like to keep the existential type.
Problem
Consider the following data model utilizing an existential: ``` data Node a = Node a (Map TypeRep AnyNode) data AnyNode = forall a. Show a => AnyNode a ``` The rules about memory footprint of standard types have been explained previously. Now, what are the rules for existential types, like `AnyNode`? Are there any optimization techniques, e.g. some workarounds using `unsafeCoerce` making it possible to elude the existential declaration? I'm asking this because a type similar to `Node` is going to be placed in a cost centre of a highly memory-intensive lib, so memory footprint is all, that's why the most dirty hacks are welcome.