sqlite-easy 1.1.0.1 → 1.1.1.0
raw patch · 6 files changed
+96/−4 lines, 6 filesdep +criteriondep +deepseqdep ~base
Dependencies added: criterion, deepseq
Dependency ranges changed: base
Files
- bench/Bench.hs +54/−0
- changelog.md +6/−0
- sqlite-easy.cabal +15/−1
- src/Database/Sqlite/Easy.hs +1/−0
- src/Database/Sqlite/Easy/Internal.hs +18/−3
- src/Database/Sqlite/Easy/Migrant.hs +2/−0
+ bench/Bench.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE StandaloneDeriving #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}++import Criterion.Main as Criterion++import GHC.Generics (Generic)+import Control.DeepSeq (NFData)+import Control.Monad+import Database.Sqlite.Easy+++deriving instance NFData SQLData++data BenchEnv = BenchEnv+ { largeSampleRows :: [[SQLData]]+ , smallSmapleRows :: [[SQLData]]+ } deriving (Generic, NFData)++main :: IO ()+main = defaultMain+ [ env setupEnv $ \ ~(BenchEnv{..}) ->+ bgroup "sqlite-easy-insert" + [ bench "1000 rows/individual" $ insertBench False smallSmapleRows+ , bench "1000 rows/bulk" $ insertBench True smallSmapleRows+ , bench "100000 rows/individual" $ insertBench False largeSampleRows+ , bench "100000 rows/bulk" $ insertBench True largeSampleRows+ ]+ ]++setupEnv :: IO BenchEnv+setupEnv =+ pure $ BenchEnv (take 100000 rows) (take 1000 rows)+ where+ rows = cycle+ [ [SQLInteger 42, SQLFloat 3.14152, SQLText "The quick brown fox jumps over the lazy dog."]+ , [SQLInteger 0, SQLFloat 12.131516, SQLText "If you've got nothing to say, start a band."]+ ]++createTable, insertTable :: SQL+createTable = "CREATE TABLE bench (b_int INTEGER, b_float REAL, b_text TEXT)"+insertTable = "INSERT INTO bench VALUES (?,?,?)"++insertBench :: Bool -> [[SQLData]] -> Benchmarkable+insertBench bulkMode rows = nfIO $+ withDb ":memory:" $ do+ run createTable+ void $ transaction $ if bulkMode+ then insertTable `runWithMany` rows+ else mapM (insertTable `runWith`) rows
changelog.md view
@@ -1,3 +1,9 @@++### 1.1.1.0++* Add `runWithMany`, which reuses a prepared statement for many parameter rows (e.g. to speed up bulk inserts) (by @michael207)+* Add benchmarking suite (by @michael207)+ ### 1.1.0.1 * Make migrations containing transactions work.
sqlite-easy.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 name: sqlite-easy-version: 1.1.0.1+version: 1.1.1.0 synopsis: A primitive yet easy to use sqlite library. description: A primitive yet easy to use sqlite library built using sqlite-direct, resource-pool and migrant. author: Gil Mizrahi@@ -55,3 +55,17 @@ -threaded -rtsopts -with-rtsopts=-N build-tool-depends: hspec-discover:hspec-discover++benchmark sqlite-easy-bench+ type: exitcode-stdio-1.0+ hs-source-dirs: bench+ main-is: Bench.hs+ other-modules:+ build-depends:+ base+ , criterion+ , deepseq+ , sqlite-easy+ default-language: Haskell2010+ ghc-options:+ -threaded -rtsopts -with-rtsopts=-N
src/Database/Sqlite/Easy.hs view
@@ -21,6 +21,7 @@ -- $running , run , runWith+ , runWithMany , SQLite , liftIO , fromString
src/Database/Sqlite/Easy/Internal.hs view
@@ -96,16 +96,31 @@ run :: SQL -> SQLite [[SQLData]] run (SQL stmt) = do db <- getDB- liftIO $ bracket (Direct.prepare db stmt) Direct.finalize fetchAll+ liftIO $ Direct.withStatement db stmt fetchAll -- | Run a SQL statement with certain parameters on a database and fetch the results. runWith :: SQL -> [SQLData] -> SQLite [[SQLData]] runWith (SQL stmt) params = do db <- getDB- liftIO $ do- bracket (Direct.prepare db stmt) Direct.finalize $ \preparedStmt -> do+ liftIO $ Direct.withStatement db stmt $ \preparedStmt -> do Direct.bind preparedStmt params fetchAll preparedStmt++-- | Run a SQL statement binding it to all given parameter rows and fetch all of the data.+-- This can significantly improve speed for cases like bulk INSERTs.+--+-- @since 1.1.1.0+runWithMany :: SQL -> [[SQLData]] -> SQLite [[[SQLData]]]+runWithMany (SQL stmt) paramsList = do+ db <- getDB+ liftIO $ Direct.withStatement db stmt $ \preparedStmt ->+ let+ runRow params = do+ Direct.reset preparedStmt+ Direct.clearBindings preparedStmt+ Direct.bind preparedStmt params+ fetchAll preparedStmt+ in mapM runRow paramsList -- | Run a statement and fetch all of the data. fetchAll :: Statement -> IO [[SQLData]]
src/Database/Sqlite/Easy/Migrant.hs view
@@ -1,5 +1,7 @@ {-# language OverloadedStrings #-} +{-# OPTIONS_GHC -fno-warn-orphans #-}+ -- | Migrations support based on @migrant-core@. module Database.Sqlite.Easy.Migrant ( module Database.Migrant.Driver.Class