@@ -11,16 +11,15 @@
1111{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver -fno-warn-orphans #-}
1212
1313module DMap
14− ( benchDMap
15− , prepareBenchDMap
14+ ( spec
1615 ) where
1716
18−import Criterion.Main (Benchmark, bench, bgroup, nf)
17+import Criterion.Main (bench, nf, whnf, env)
1918
2019import Prelude hiding (lookup)
2120
22−import Control.DeepSeq (rnf)
23−import Control.Exception
21+import Spec
22+import Control.DeepSeq (NFData(..))
2423import Data.Maybe (fromJust)
2524import Data.Proxy (Proxy (..))
2625import Data.Type.Equality ((:~:) (..))
@@ -35,12 +34,20 @@ import Data.Some (Some (This))
3534
3635type TypeRepMap = DMap TypeRep
3736
38−benchDMap :: Benchmark
39−benchDMap = bgroup "dependent map"
40− [ bench "lookup" $ nf tenLookups bigMap
41− -- , bench "insert new" $ whnf (\x -> rknf $ insert x bigMap) (Proxy :: Proxy 9999999999)
42− -- , bench "update old" $ whnf (\x -> rknf $ insert x bigMap) (Proxy :: Proxy 1)
43− ]
37+
38+spec :: BenchSpec
39+spec = BenchSpec
40+ { benchLookup = Just $ \name ->
41+ env mkBigMap $ \ ~(DMapNF bigMap) ->
42+ bench name $ nf tenLookups bigMap
43+ , benchInsertSmall = Just $ \name ->
44+ bench name $ whnf (inserts empty 10) (Proxy @ 99999)
45+ , benchInsertBig = Just $ \name ->
46+ env mkBigMap $ \ ~(DMapNF bigMap) ->
47+ bench name $ whnf (inserts bigMap 1) (Proxy @ 99999)
48+ , benchUpdateSmall = Nothing -- Not implemented
49+ , benchUpdateBig = Nothing -- Not implemented
50+ }
4451
4552tenLookups :: TypeRepMap (Proxy :: Nat -> *)
4653 -> ( Proxy 10, Proxy 20, Proxy 30, Proxy 40
@@ -51,9 +58,20 @@ tenLookups tmap = (lp, lp, lp, lp, lp, lp, lp, lp)
5158 lp :: forall (a :: Nat) . Typeable a => Proxy a
5259 lp = fromJust $ lookup (typeRep @a) tmap
5360
61+inserts :: forall a . (KnownNat a)
62+ => TypeRepMap (Proxy :: Nat -> *)
63+ -> Int
64+ -> Proxy (a :: Nat)
65+ -> TypeRepMap (Proxy :: Nat -> *)
66+inserts !c 0 _ = c
67+inserts !c n x = inserts
68+ (insert (typeRep @ a) x c)
69+ (n-1)
70+ (Proxy :: Proxy (a+1))
71+
5472-- TypeRepMap of 10000 elements
55−bigMap :: TypeRepMap (Proxy :: Nat -> *)
56−bigMap = buildBigMap 10000 (Proxy :: Proxy 0) empty
73+mkBigMap :: IO (DMapNF (Proxy :: Nat -> *))
74+mkBigMap = pure . DMapNF $ buildBigMap 10000 (Proxy :: Proxy 0) empty
5775
5876buildBigMap :: forall a . (KnownNat a)
5977 => Int
@@ -64,11 +82,12 @@ buildBigMap 1 x = insert (typeRep @a) x
6482buildBigMap n x = insert (typeRep @a) x
6583 . buildBigMap (n - 1) (Proxy @(a + 1))
6684
67−rknf :: TypeRepMap f -> ()
68−rknf = rnf . map (\(This t) -> typeRepFingerprint t) . keys
85+-- | Wrapper that provides NFData instance to the 'DMap' structure.
86+newtype DMapNF f = DMapNF (TypeRepMap f)
6987
70−prepareBenchDMap :: IO ()
71−prepareBenchDMap = evaluate (rknf bigMap)
88+instance NFData (DMapNF f) where
89+ rnf (DMapNF x) =
90+ rnf . map (\(This t) -> typeRepFingerprint t) $ keys x
7291
7392instance GEq TypeRep where
7493 geq :: TypeRep a -> TypeRep b -> Maybe (a :~: b)