{-# 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 l = HR2 k k m = HR2 l l n = HR2 m m o = HR2 n n p = HR2 o o q = HR2 p p r = HR2 q q s = HR2 r r t = HR2 s s u = HR2 t t v = HR2 u u w = HR2 v v x = HR2 w w y = HR2 x x z = HR2 y y za = HR2 z z zb = HR2 za za zc = HR2 zb zb zd = HR2 zc zc in zd bigGenericRolledDS :: GenericRolled bigGenericRolledDS = let a = GR0 b = GR1 $ Just 1 c = GR1 $ Nothing d = GR1 $ Just 3 e = GR2 a b f = GR2 c d g = GR2 e e h = GR2 f f i = GR2 e f j = GR2 g h k = GR2 i j l = GR2 k k m = GR2 l l n = GR2 m m o = GR2 n n p = GR2 o o q = GR2 p p r = GR2 q q s = GR2 r r t = GR2 s s u = GR2 t t v = GR2 u u w = GR2 v v x = GR2 w w y = GR2 x x z = GR2 y y za = GR2 z z zb = GR2 za za zc = GR2 zb zb zd = GR2 zc zc in zd main :: IO () main = defaultMain [ bcompare [ bench "handrolled" $ whnf hash bigHandRolledDS , bench "generic" $ whnf hash bigGenericRolledDS ] ]