[pypy-dev] Slow sqlite user defined functions with pypy.

Elefterios Stamatogiannakis estama at gmail.com
Thu Nov 17 02:13:06 CET 2011


The following code is a lot slower with pypy as compared to CPython. The 
code mainly measures the time taken to execute a simple SQLite user 
defined function (UDF) and a more complex one, 1000000 times each.

Execution time for both queries is:
CPython 2.7: 7 sec 489 msec
Pypy nightly build: 28 sec 753 msec

Execution time for simple query only is:
CPython 2.7: 1 sec 39 msec
Pypy nightly build: 13 sec 645 msec

Pypy seems to not jit at all when a (pypy) Python function is called from C.

Also based on the simple query times, pypy seems to have massive 
overhead (nearly 13 times slower) when executing callbacks from C code.

lefteris.

--- code --

import sqlite3
import datetime

# Simple function
def testfun(*args):

     return 1

# Complex function
def sectohuman(*args):

     secs=int(args[0])
     h=''
     days=secs/86400
     if days > 0:
         h+=str(days)+' day'
         if days > 1:
             h+='s'
         h+=' '
         secs=secs % 86400
     hours=secs/3600
     if hours > 0:
         h+=str(hours)+' hour'
         if hours > 1:
             h+='s'
         h+=' '
         secs=secs % 3600
     mins=secs/60
     if mins > 0:
         h+=str(mins)+' min '
         secs=secs % 60
     if secs > 0:
         h+=str(secs)+' sec'

     return h

con=sqlite3.Connection('')

con.create_function('testfun', -1, testfun)
con.create_function('sectohuman', -1, sectohuman)

cur=con.cursor()

cur.execute('create table l(a);')
cur.execute('begin;')

for i in xrange(1000000):
     cur.execute('insert into l values(?)',(i,))

before=datetime.datetime.now()

# Simple query
a=list(cur.execute('select sum(testfun(a)) as s from l'))

# Complex query
a=list(cur.execute('select sum(length(sectohuman(a))) as s from l'))

after=datetime.datetime.now()

tmdiff=after-before

print "Execution time is %s min. %s sec %s msec" 
%((int(tmdiff.days)*24*60+(int(tmdiff.seconds)/60),(int(tmdiff.seconds)%60),(int(tmdiff.microseconds)/1000)))



More information about the pypy-dev mailing list