{-# LANGUAGE DeriveGeneric #-}
{-# OPTIONS_GHC -Wall -O2 #-}
module Main ( main ) where
import Criterion
import Criterion.Main
import Data.Hashable
import Data.Hashable.Generic
import GHC.Generics
data HandRolled = HR0
| HR1 (Maybe Int)
| HR2 HandRolled HandRolled
data GenericRolled = GR0
| GR1 (Maybe Int)
| GR2 GenericRolled GenericRolled
deriving Generic
instance Hashable HandRolled where
hashWithSalt salt HR0 = hashWithSalt salt $ (Left () :: Either () ())
hashWithSalt salt (HR1 mi) = hashWithSalt salt $ (Right $ Left mi :: Either () (Either (Maybe Int) ()))
hashWithSalt salt (HR2 x y) = hashWithSalt salt $ (Right $ Right (x, y) :: Either () (Either () (HandRolled, HandRolled)))
instance Hashable GenericRolled where
hashWithSalt s x = gHashWithSalt s x
bigHandRolledDS :: HandRolled
bigHandRolledDS = let a = HR0
b = HR1 $ Just 1
c = HR1 $ Nothing
d = HR1 $ Just 3
e = HR2 a b
f = HR2 c d
g = HR2 e e
h = HR2 f f
i = HR2 e f
j = HR2 g h
k = HR2 i j
in HR2 k k
bigGenericRolledDS :: GenericRolled
bigGenericRolledDS = f bigHandRolledDS
where
f HR0 = GR0
f (HR1 x) = GR1 x
f (HR2 x y) = GR2 (f x) (f y)
main :: IO ()
main = defaultMain [ bcompare [ bench "handrolled" $ whnf hash bigHandRolledDS
, bench "generic" $ whnf hash bigGenericRolledDS
]
]