hasql-0.20: benchmarks/Main.hs
module Main where
import Prelude
import Bug
import Criterion
import Criterion.Main
import qualified Hasql.Connection as A
import qualified Hasql.Batch as J
import qualified Hasql.Session as F
import qualified Hasql.Statement as G
import qualified Hasql.DecodeResult as B
import qualified Hasql.DecodeRow as C
import qualified Hasql.DecodePrimitive as D
import qualified Data.Vector as H
import qualified Control.Foldl as I
main =
do
connection <- connect
let
sessionBench :: NFData a => String -> F.Session a -> Benchmark
sessionBench name session =
bench name (nfIO (runSession session))
where
runSession session =
do
Right result <- A.session connection session
return result
in
defaultMain
[
sessionBench "singleLargeResultInVector" singleLargeResultInVectorSession,
sessionBench "singleLargeResultInRevList" singleLargeResultInRevListSession,
sessionBench "manyLargeResultsInVector" manyLargeResultsInVectorSession,
sessionBench "manyLargeResultsInVectorInBatch" manyLargeResultsInVectorInBatchSession,
sessionBench "manySmallResults" manySmallResultsSession,
sessionBench "manySmallResultsInBatch" manySmallResultsInBatchSession
]
connect :: IO A.Connection
connect =
do
openingResult <- A.open (A.TCPConnectionSettings "localhost" 5432) "postgres" "" Nothing handleErrorOrNotification
case openingResult of
Left error -> fail (showString "Can't connect: " (show error))
Right connection -> return connection
where
handleErrorOrNotification x =
putStrLn ("Async event: " <> show x)
-- * Sessions
-------------------------
singleLargeResultInVectorSession :: F.Session (Vector (Int64, Int64))
singleLargeResultInVectorSession =
F.batch (manyRowsBatch B.vector)
singleLargeResultInRevListSession :: F.Session [(Int64, Int64)]
singleLargeResultInRevListSession =
F.batch (manyRowsBatch B.revList)
manyLargeResultsInVectorSession :: F.Session [Vector (Int64, Int64)]
manyLargeResultsInVectorSession =
replicateM 1000 (F.batch (manyRowsBatch B.vector))
manyLargeResultsInVectorInBatchSession :: F.Session [Vector (Int64, Int64)]
manyLargeResultsInVectorInBatchSession =
F.batch (replicateM 1000 (manyRowsBatch B.vector))
manySmallResultsSession :: F.Session [(Int64, Int64)]
manySmallResultsSession =
replicateM 1000 (F.batch singleRowBatch)
manySmallResultsInBatchSession :: F.Session [(Int64, Int64)]
manySmallResultsInBatchSession =
F.batch (replicateM 1000 singleRowBatch)
-- * Queries
-------------------------
singleRowBatch :: J.Batch (Int64, Int64)
singleRowBatch =
J.statement (G.prepared "select 1, 2" conquer decode) ()
where
decode =
B.head ((,) <$> C.primitive D.int8 <*> C.primitive D.int8)
{-# INLINE manyRowsBatch #-}
manyRowsBatch :: (C.DecodeRow (Int64, Int64) -> B.DecodeResult result) -> J.Batch result
manyRowsBatch decodeResult =
J.statement (G.prepared template mempty decode) ()
where
template =
"SELECT generate_series(0,1000) as a, generate_series(1000,2000) as b"
decode =
decodeResult $
tuple <$> C.primitive D.int8 <*> C.primitive D.int8
where
tuple !a !b =
(a, b)