module Main (main) where import Criterion.Main import Data.HashMap.Lazy (HashMap) import qualified Data.HashMap.Lazy as HashMap import Data.HashTable.Class (HashTable) import Data.HashTable.IO (BasicHashTable, CuckooHashTable, IOHashTable, LinearHashTable) import qualified Data.HashTable.IO as IOHashTable import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap import Data.List (foldl') import Data.Map (Map) import qualified Data.Map as Map import Test.QuickCheck (generate, vector) size :: Int size = 1000000 type InsertInput = ([Int], [Int]) generateInsertInput :: Int -> IO InsertInput generateInsertInput k = (,) <$> return [1 .. k] <*> generate (vector k) type LookupInput = [Int] generateLookupInput :: Int -> IO LookupInput generateLookupInput k = generate (vector k) main :: IO () main = defaultMain [ env (generateInsertInput size) $ \ ~(sorted, random) -> bgroup "insert" [ bgroup "Data.Map" [ bench "sorted" $ whnf insertMap sorted , bench "random" $ whnf insertMap random ] , bgroup "Data.IntMap" [ bench "sorted" $ whnf insertIntMap sorted , bench "random" $ whnf insertIntMap random ] , bgroup "Data.HashMap.Lazy" [ bench "sorted" $ whnf insertHashMap sorted , bench "random" $ whnf insertHashMap random ] , bgroup "Data.HashTable.ST.Basic" [ bench "sorted" $ whnfIO (insertHashTableIO sorted :: IO (BasicHashTable Int Int)) , bench "random" $ whnfIO (insertHashTableIO random :: IO (BasicHashTable Int Int)) ] , bgroup "Data.HashTable.ST.Cuckoo" [ bench "sorted" $ whnfIO (insertHashTableIO sorted :: IO (CuckooHashTable Int Int)) , bench "random" $ whnfIO (insertHashTableIO random :: IO (CuckooHashTable Int Int)) ] , bgroup "Data.HashTable.ST.Linear" [ bench "sorted" $ whnfIO (insertHashTableIO sorted :: IO (LinearHashTable Int Int)) , bench "random" $ whnfIO (insertHashTableIO random :: IO (LinearHashTable Int Int)) ] ] , env (generateLookupInput size) $ \ks -> bgroup "lookup" [ bench "Data.Map" $ nf lookupMap ks , bench "Data.IntMap" $ nf lookupIntMap ks , bench "Data.HashMap.Lazy" $ nf lookupHashMap ks ] ] insertMap :: [Int] -> Map Int Int insertMap = foldl' (\m k -> Map.insert k 1 m) Map.empty insertIntMap :: [Int] -> IntMap Int insertIntMap = foldl' (\m k -> IntMap.insert k 1 m) IntMap.empty insertHashMap :: [Int] -> HashMap Int Int insertHashMap = foldl' (\m k -> HashMap.insert k 1 m) HashMap.empty insertHashTableIO :: HashTable h => [Int] -> IO (IOHashTable h Int Int) insertHashTableIO xs = do ht <- IOHashTable.new mapM_ (\k -> IOHashTable.insert ht k 1) xs return ht aMap :: Map Int Int aMap = Map.fromAscList [(k, 1) | k <- [1 .. size]] lookupMap :: [Int] -> [Maybe Int] lookupMap = map (`Map.lookup` aMap) aIntMap :: IntMap Int aIntMap = IntMap.fromAscList [(k, 1) | k <- [1 .. size]] lookupIntMap :: [Int] -> [Maybe Int] lookupIntMap = map (`IntMap.lookup` aIntMap) aHashMap :: HashMap Int Int aHashMap = HashMap.fromList [(k, 1) | k <- [1 .. size]] lookupHashMap :: [Int] -> [Maybe Int] lookupHashMap = map (`HashMap.lookup` aHashMap)