Skip to content

Commit bddf64d

Browse files
Encoding benchmark
1 parent 3b6c72e commit bddf64d

File tree

5 files changed

+114
-65
lines changed

5 files changed

+114
-65
lines changed

bench/Codecs.hs

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
module Main where
2+
3+
import Data.ByteString.Lazy (toStrict)
4+
import Data.ByteString.Builder (toLazyByteString)
5+
import Data.ByteString (ByteString)
6+
import Data.Monoid
7+
import System.IO.Unsafe
8+
import Data.Vector as V(fromList, empty)
9+
import Criterion.Main
10+
import Data.Time
11+
import Data.UUID
12+
import Data.UUID.V4 (nextRandom)
13+
import Data.Scientific
14+
15+
import Database.PostgreSQL.Protocol.Types
16+
import Database.PostgreSQL.Protocol.Encoders
17+
import Database.PostgreSQL.Protocol.Store.Encode
18+
import Database.PostgreSQL.Protocol.Store.Decode
19+
import qualified Database.PostgreSQL.Protocol.Codecs.Decoders as PD
20+
import qualified Database.PostgreSQL.Protocol.Codecs.Encoders as PE
21+
import qualified Database.PostgreSQL.Protocol.Codecs.PgTypes as PGT
22+
23+
main :: IO ()
24+
main = defaultMain
25+
[ bgroup "Encoding"
26+
[ bench "Message" $ nf encodeMessage queryParams
27+
, bench "Scientific" $ nf (runEncode . PE.numeric) testScientific
28+
, bench "UTCTime" $ nf (runEncode . PE.timestamptz) testUTCTime
29+
, bench "UUID" $ nf (runEncode . PE.uuid) testUUID
30+
]
31+
]
32+
33+
type QueryParams
34+
= (Bool, ByteString, Double, DiffTime, Scientific, UTCTime, UUID)
35+
36+
{-# NOINLINE queryParams #-}
37+
queryParams :: QueryParams
38+
queryParams =
39+
( True
40+
, "aaaaaaaaaaaa"
41+
, 3.1415926
42+
, fromIntegral 20000000
43+
, scientific 1111111111111 (-18)
44+
, unsafePerformIO getCurrentTime
45+
, unsafePerformIO nextRandom
46+
)
47+
48+
testScientific :: Scientific
49+
testScientific = scientific 11111111111111 (-18)
50+
51+
{-# NOINLINE testUTCTime #-}
52+
testUTCTime :: UTCTime
53+
testUTCTime = unsafePerformIO getCurrentTime
54+
55+
{-# NOINLINE testUUID #-}
56+
testUUID :: UUID
57+
testUUID = unsafePerformIO nextRandom
58+
59+
encodeMessage :: QueryParams -> ByteString
60+
encodeMessage params = runEncode $
61+
encodeClientMessage parseMessage <> encodeClientMessage bindMessage
62+
where
63+
bindMessage = Bind (PortalName "") stmtName Binary
64+
(encodedParams params) Binary
65+
encodedParams (a, b, c, d, e, f, g) = V.fromList
66+
[ Just . runEncode $ PE.bool a
67+
, Just . runEncode $ PE.bytea b
68+
, Just . runEncode $ PE.float8 c
69+
, Just . runEncode $ PE.interval d
70+
, Just . runEncode $ PE.numeric e
71+
, Just . runEncode $ PE.timestamptz f
72+
, Just . runEncode $ PE.uuid g
73+
]
74+
parseMessage = Parse stmtName stmt oids
75+
stmtName = StatementName "_pw_statement_0010"
76+
stmt = StatementSQL
77+
"SELECT a, b, c FROM table_name WHERE name LIKE $1 AND a > $2"
78+
oids = V.fromList $ map PGT.oidType
79+
[ PGT.bool
80+
, PGT.bytea
81+
, PGT.float8
82+
, PGT.interval
83+
, PGT.numeric
84+
, PGT.timestamptz
85+
, PGT.uuid
86+
]
87+

bench/Encoders.hs

-59
This file was deleted.

postgres-wire.cabal

+21-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,24 @@ benchmark postgres-wire-bench
113113
hs-source-dirs:
114114
bench
115115
main-is: Bench.hs
116-
other-modules: Encoders
116+
build-depends: base
117+
, postgres-wire
118+
, bytestring
119+
, vector
120+
, postgresql-libpq
121+
, clock
122+
, optparse-applicative
123+
ghc-options: -O2 -threaded -rtsopts -with-rtsopts=-s
124+
default-language: Haskell2010
125+
default-extensions:
126+
OverloadedStrings
127+
GeneralizedNewtypeDeriving
128+
129+
benchmark postgres-wire-bench-codecs
130+
type: exitcode-stdio-1.0
131+
hs-source-dirs:
132+
bench
133+
main-is: Codecs.hs
117134
build-depends: base
118135
, postgres-wire
119136
, bytestring
@@ -123,6 +140,9 @@ benchmark postgres-wire-bench
123140
, postgresql-libpq
124141
, clock
125142
, optparse-applicative
143+
, time
144+
, uuid
145+
, scientific
126146
ghc-options: -O2 -threaded -rtsopts -with-rtsopts=-s
127147
default-language: Haskell2010
128148
default-extensions:

src/Database/PostgreSQL/Protocol/Codecs/Encoders.hs

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ bsJsonBytes bs = putWord8 1 <> putByteString bs
7676
{-# INLINE numeric #-}
7777
numeric :: Scientific -> Encode
7878
numeric n =
79-
let (weight, scale, digits) = scientificToNumeric n
80-
in putWord16BE (fromIntegral $ length digits)
79+
let (count, weight, scale, digits) = scientificToNumeric n
80+
in putWord16BE count
8181
<> putInt16BE weight
8282
<> putWord16BE (toNumericSign n)
8383
<> putWord16BE scale

src/Database/PostgreSQL/Protocol/Codecs/Numeric.hs

+4-3
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@ import Data.Scientific (Scientific, scientific, base10Exponent, coefficient)
99
import Data.List (unfoldr)
1010

1111
{-# INLINE scientificToNumeric #-}
12-
scientificToNumeric :: Scientific -> (Int16, Word16, [Word16])
12+
scientificToNumeric :: Scientific -> (Word16, Int16, Word16, [Word16])
1313
scientificToNumeric number =
1414
let a = base10Exponent number `mod` nBaseDigits
1515
adjExp = base10Exponent number - a
1616
adjCoef = coefficient number * (10 ^ a)
1717
digits = integerToDigits $ abs adjCoef
18-
weight = fromIntegral $ length digits + adjExp `div` nBaseDigits - 1
18+
count = length digits
19+
weight = fromIntegral $ count + adjExp `div` nBaseDigits - 1
1920
scale = fromIntegral . negate $ min (base10Exponent number) 0
20-
in (weight, scale, digits)
21+
in (fromIntegral count, weight, scale, digits)
2122

2223
{-# INLINE numericToScientific #-}
2324
numericToScientific :: Integer -> Int16 -> [Word16] -> Scientific

0 commit comments

Comments
 (0)