git.iko.soy/typeable/postgresql-simple
on master help sign in
Copy every field, all the time.

This change is for improved performance in typical use cases. Unfortunately, this is a tradeoff, and not always a win either It turns out that `LibPQ.getvalue'` is substantially faster for small bytestrings than `LibPQ.getvalue`. Apparently, this is due to the fact that `getvalue'` (indirectly) calls `mallocForeignPtrBytes`, which is "heavily optimized", whereas `getvalue` calls `newForeignPtr` and sets up a finalizer that touches the `LibPQ.Result` to prevent it from being freed by GHC's garbage collector. Presumably, there is a point at which `getvalue` becomes faster than `getvalue'`, as the former should be O(1) whereas the latter is `O(n)` due to memcpy. However, for common use cases this is a moot point, as postgresql-simple does a memcpy upon conversion to a `ByteString` anyway. The other conversions don't copy the memory, but most types are guaranteed to be short enough that this switch is a win. The only pre-packaged conversions where this change is a loss is when dealing with big arrays, big hstores, and big json documents. Just how big where the crossover point is needs to be researched.

commit8635f8819ea62096b055df59c9b77a8c77328222 authorLeon P Smith <leon@melding-monads.com> dateSat 21 Dec 2013, 05:46 (13 years ago) parentb2de4cf
2 files changed+3−14
src/Database/PostgreSQL/Simple/FromField.hs+2−13 src/Database/PostgreSQL/Simple/FromRow.hs+1−1
src/Database/PostgreSQL/Simple/FromField.hs+2−13
@@ -166,17 +166,6 @@ class FromField a where
166166 -- Returns a list of exceptions if the conversion fails. In the case of
167167 -- library instances, this will usually be a single 'ResultError', but
168168 -- may be a 'UnicodeException'.
169− --
170− -- Note that retaining any reference to the 'Field' or 'ByteString'
171− -- arguments causes the entire @LibPQ.'PQ.Result'@ to be retained.
172− -- Thus, as a rule of thumb, implementations of 'fromField' should
173− -- not refer to these values after the result has been evaluated
174− -- to WHNF. But it can be profitable to break this rule when you
175− -- know it won't cause memory management problems.
176− --
177− -- The instances included with postgresql-simple follow this rule
178− -- of thumb (modulo bugs). For example, the instance for 'ByteString'
179− -- uses 'B.copy' to avoid such a reference.
180169
181170-- | Returns the data type name. This is the preferred way of identifying
182171-- types that do not have a stable type oid, such as types provided by
@@ -320,7 +309,7 @@ unBinary (Binary x) = x
320309instance FromField SB.ByteString where
321310 fromField f dat = if typeOid f == $(inlineTypoid TI.bytea)
322311 then unBinary <$> fromField f dat
323− else doFromField f okText' (pure . B.copy) dat
312+ else doFromField f okText' pure dat
324313
325314-- | oid
326315instance FromField PQ.Oid where
@@ -340,7 +329,7 @@ unescapeBytea f str = case unsafeDupablePerformIO (PQ.unescapeBytea str) of
340329instance FromField (Binary SB.ByteString) where
341330 fromField f dat = case format f of
342331 PQ.Text -> doFromField f okBinary (unescapeBytea f) dat
343− PQ.Binary -> doFromField f okBinary (pure . Binary . B.copy) dat
332+ PQ.Binary -> doFromField f okBinary (pure . Binary) dat
344333
345334-- | bytea
346335instance FromField (Binary LB.ByteString) where
src/Database/PostgreSQL/Simple/FromRow.hs+1−1
@@ -70,7 +70,7 @@ class FromRow a where
7070 fromRow :: RowParser a
7171
7272getvalue :: PQ.Result -> PQ.Row -> PQ.Column -> Maybe ByteString
73−getvalue result row col = unsafeDupablePerformIO (PQ.getvalue result row col)
73+getvalue result row col = unsafeDupablePerformIO (PQ.getvalue' result row col)
7474
7575nfields :: PQ.Result -> PQ.Column
7676nfields result = unsafeDupablePerformIO (PQ.nfields result)