I have a simple network protocol client (it's a part of this:
http://sqlcached.sourceforge.net) implemented in Python, PHP and C.
Everything's fine, except that the Python implementation is the slowest
- up to 30% slower than the PHP version (which implements exactly the
same logic, in a class).
In typical usage (also in the benchmark), an object is created and
..query is called repeatedly. Typical numbers for the benchmark are:
For Python version:
Timing 100000 INSERTs...
5964.4 qps
Timing 100000 SELECTs...
7491.0 qps
For PHP version:
Timing 100000 inserts...
7820.2 qps
Timing 100000 selects...
9926.2 qps
The main part of the client class is:
----
import os, socket, re
class SQLCacheD_Excep tion(Exception) :
pass
class SQLCacheD:
DEFAULT_UNIX_SO CKET = '/tmp/sqlcached.sock'
SC_VER_SIG = 'sqlcached-1'
SOCK_UNIX = 'unix'
SOCK_TCP = 'tcp'
re_rec = re.compile(r"\+ REC (\d+), (\d+)")
re_ok = re.compile(r"\+ OK (.+)")
re_ver = re.compile(r"\+ VER (.+)")
def __init__(self, host = '/tmp/sqlcached.sock' , type = 'unix'):
if type != SQLCacheD.SOCK_ UNIX:
raise
self.sock = socket.socket(s ocket.AF_UNIX, socket.SOCK_STR EAM)
self.sock.conne ct(host)
self.sf = self.sock.makef ile('U', 4000)
self.sf.write(" VER %s\r\n" % SQLCacheD.SC_VE R_SIG)
self.sf.flush()
if self.sf.readlin e().rstrip() != '+VER %s' % SQLCacheD.SC_VE R_SIG:
raise SQLCacheD_Excep tion("Handshake failure (invalid
version signature?)")
def query(self, sql):
self.sf.write(" SQL %s\r\n" % sql)
self.sf.flush()
resp = self.sf.readlin e().rstrip()
m = SQLCacheD.re_re c.match(resp)
if m != None: # only if some rows are returned (SELECT)
n_rows = int(m.group(1))
n_cols = int(m.group(2))
cols = []
for c in xrange(n_cols):
cols.append(sel f.sf.readline() .rstrip())
rs = []
for r in xrange(n_rows):
row = {}
for c in cols:
row[c] = self.sf.readlin e().rstrip()
rs.append(row)
return rs
m = SQLCacheD.re_ok .match(resp)
if m != None: # no rows returned (e.g. INSERT/UPDATE/DELETE)
return True
raise SQLCacheD_Excep tion(resp)
----
My question is: Am I missing something obvious? The C implementation is
(as expected) the fastest with result of 10000:15000, but somehow I
expected the Python one to be closer to, or even faster than PHP.
I tried using 'r' mode for .makefile() but it had no significant effect.