Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generating queries can be quadratic in time #70

Closed
lpsmith opened this issue Jul 8, 2013 · 3 comments
Closed

Generating queries can be quadratic in time #70

lpsmith opened this issue Jul 8, 2013 · 3 comments

Comments

@lpsmith
Copy link
Owner

lpsmith commented Jul 8, 2013

Possibly related to #39, it appears as though query generation is quadratic when it involves escaping via libpq's escapeStringConn command. Here's a simple test case that reproduces the behavior:

{-# LANGUAGE OverloadedStrings, BangPatterns #-}

import Database.PostgreSQL.Simple
import System.Environment

main = do
   (nstr:_) <- getArgs
   let n = read nstr :: Int
   c <- connectPostgreSQL ""
   !q <- formatMany c "insert into foo values (?,?)" [ (i,show i) | i <- [1..n] ]
   close c

Note that this isn't a problem if you replace show i by say, i^2 or whatnot.

@lpsmith
Copy link
Owner Author

lpsmith commented Jul 8, 2013

Ok, I did a bit of information gathering and discovered that mysql-simple does not exhibit this bug, while even version 0.0 of postgresql-simple does. I find this slightly surprising as I didn't change Bryan's query generation code too much; I was expecting this problem to have either been introduced sometime after the first release or inherited from mysql-simple, but clearly I did something wrong in the initial port.

@lpsmith
Copy link
Owner Author

lpsmith commented Jul 8, 2013

Whatever the problem is, at least some of it appears to be inside either the libpq C library and/or the postgresql-libpq haskell binding. This appears to exhibit non-linear behavior, though perhaps not quite quadratic, as doubling the number of escaped strings takes about 3x longer:

{-# LANGUAGE OverloadedStrings #-}

import qualified Database.PostgreSQL.LibPQ as PQ
import System.Environment
import qualified Data.ByteString.Char8 as B

main = do
    (nstr : _) <- getArgs
    let n = read nstr :: Int
    c <- PQ.connectdb ""
    stat <- PQ.status c
    case stat of
      PQ.ConnectionOk -> do
          xs <- loop c n []
          print (xs == xs)
          PQ.finish c
      _ -> fail "connection failed"

loop c n acc =
  if n == 0
  then return acc
  else do
    a <- PQ.escapeStringConn c "test"
    loop c (n-1) (a:acc)

@lpsmith
Copy link
Owner Author

lpsmith commented Jul 9, 2013

Ok, I fixed up postgresql-libpq's binding to escapeStringConn, and the performance looks a lot more reasonable. I'm going to call this bug closed for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant