
Hello All, I've recently modified my existing project to support dynamic data (using 'Data.Dynamic'), and despite my earlier benchmarks on 'Dynamic', the program slowed down by a factor of 10. Profiler says that 'fromDynamic' is consuming 60% of the CPU time (with -O2). Using the below function instead of 'fromDynamic' seems to make coercion 20 times faster (thereby solving my problem):
{-# OPTIONS -fglasgow-exts #-}
import GHC.Prim
data Dynamic' = Dynamic' TypeRep Any
fromDynamic' :: forall a. Typeable a => Dynamic -> Maybe a fromDynamic' d = let Dynamic' t v = unsafeCoerce# d in if t == typeOf (undefined :: a) then Just (unsafeCoerce# v) else Nothing
I was able to reproduce the same result from scratch. The only difference with the standard implementation (I put it below for reference), other than the first ugly unsafeCoerce#, seems to be existential quantification (i.e. When I replace "if t == typeOf (undefined :: a) ..." with the "case ..." below, performance goes down again.).
fromDynamic :: Typeable a => Dynamic -> Maybe a fromDynamic (Dynamic t v) = case unsafeCoerce v of r | t == typeOf r -> Just r | otherwise -> Nothing
So what is causing the improvement, or am I missing something? Thanks. -- Gokhan