packages feed

perfecthash-0.2.0: benchmark/Main.hs

{-# LANGUAGE OverloadedStrings #-}
import           Control.DeepSeq
import           Control.Exception     (bracket_, evaluate)
import           Control.Monad         (forM)
import           Criterion.Main
import           Data.Array.IO         (IOArray, newListArray, readArray,
                                        writeArray)
import qualified Data.ByteString.Char8 as BS8
import qualified Data.HashMap.Strict   as HashMap
import qualified Data.List             as DL
import qualified Data.Map              as Map
import qualified Data.PerfectHash      as PH
import           GHC.Profiling

import           System.Random

-- | Randomly shuffle a list
--   /O(N)/
shuffle :: [a] -> IO [a]
shuffle xs = do
        ar <- newArray n xs
        forM [1..n] $ \i -> do
            j <- randomRIO (i,n)
            vi <- readArray ar i
            vj <- readArray ar j
            writeArray ar j vi
            return vj
  where
    n = length xs
    newArray :: Int -> [a] -> IO (IOArray Int a)
    newArray n xs =  newListArray (1,n) xs

main = do
  stopProfTimer
  ws <- BS8.lines <$> BS8.readFile "/usr/share/dict/words"
  let al = zip ws ([1..] :: [Int])
      m = Map.fromList al
      hs = HashMap.fromList al
      -- let us assume that the dictionary contains no embedded nulls.
      Just ph = PH.fromList al
  randomised <- evaluate . force =<< shuffle (concat $ replicate 3 ws)
  evaluate $ force m
  evaluate $ force hs
  evaluate $ force hs
  defaultMain [
    bgroup "fib" [ bench "Data.Map"          $ nf (map (`Map.lookup` m)) randomised
                 , bench "Data.PerfectHash"  $ nf (map (`PH.lookup` ph)) randomised
                   -- bracket_ startProfTimer stopProfTimer

                 , bench "Data.HashMap"      $ nf (map (`HashMap.lookup` hs)) randomised
--                 , bench "Data.List"         $ whnf (`DL.lookup` al) "exorbitant"
                 ]
    ]