| 1 |
"""Benchmark for Geniusql.""" |
|---|
| 2 |
|
|---|
| 3 |
import datetime |
|---|
| 4 |
import os |
|---|
| 5 |
thisdir = os.path.dirname(__file__) |
|---|
| 6 |
import sys |
|---|
| 7 |
import time |
|---|
| 8 |
|
|---|
| 9 |
import geniusql |
|---|
| 10 |
from geniusql import logic, logicfuncs |
|---|
| 11 |
logicfuncs.init() |
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
class ZooMark(object): |
|---|
| 15 |
|
|---|
| 16 |
def step_1_create_tables(self): |
|---|
| 17 |
Animal = schema.table('Animal') |
|---|
| 18 |
Animal['ID'] = schema.column(int, autoincrement=True, key=True) |
|---|
| 19 |
Animal['ZooID'] = schema.column(int) |
|---|
| 20 |
Animal.add_index('ZooID') |
|---|
| 21 |
Animal['Name'] = schema.column(hints={'bytes': 100}) |
|---|
| 22 |
Animal['Species'] = schema.column(hints={'bytes': 100}) |
|---|
| 23 |
Animal['Legs'] = schema.column(int, default=4) |
|---|
| 24 |
Animal['LastEscape'] = schema.column(datetime.datetime) |
|---|
| 25 |
Animal['Lifespan'] = schema.column(float, hints={'precision': 4}) |
|---|
| 26 |
Animal['MotherID'] = schema.column(int) |
|---|
| 27 |
Animal['PreferredFoodID'] = schema.column(int) |
|---|
| 28 |
Animal['AlternateFoodID'] = schema.column(int) |
|---|
| 29 |
Animal.references['Animal'] = ('ID', 'Animal', 'MotherID') |
|---|
| 30 |
schema['Animal'] = Animal |
|---|
| 31 |
|
|---|
| 32 |
Zoo = schema.table('Zoo') |
|---|
| 33 |
Zoo['ID'] = schema.column(int, autoincrement=True, key=True) |
|---|
| 34 |
Zoo.add_index('ID') |
|---|
| 35 |
Zoo['Name'] = schema.column(hints={'bytes': 255}) |
|---|
| 36 |
Zoo['Founded'] = schema.column(datetime.date) |
|---|
| 37 |
Zoo['Opens'] = schema.column(datetime.time) |
|---|
| 38 |
Zoo['LastEscape'] = schema.column(datetime.datetime) |
|---|
| 39 |
Zoo['Admission'] = schema.column(float) |
|---|
| 40 |
|
|---|
| 41 |
Zoo.references['Animal'] = ('ID', 'Animal', 'ZooID') |
|---|
| 42 |
schema['Zoo'] = Zoo |
|---|
| 43 |
|
|---|
| 44 |
def step_1a_populate(self): |
|---|
| 45 |
Zoo = schema['Zoo'] |
|---|
| 46 |
Animal = schema['Animal'] |
|---|
| 47 |
|
|---|
| 48 |
wap = Zoo.insert(Name='Wild Animal Park', |
|---|
| 49 |
Founded=datetime.date(2000, 1, 1), |
|---|
| 50 |
|
|---|
| 51 |
|
|---|
| 52 |
Opens=datetime.time(8, 15, 59), |
|---|
| 53 |
LastEscape=datetime.datetime(2004, 7, 29, 5, 6, 7), |
|---|
| 54 |
Admission=4.95, |
|---|
| 55 |
)['ID'] |
|---|
| 56 |
|
|---|
| 57 |
sdz = Zoo.insert(Name = 'San Diego Zoo', |
|---|
| 58 |
|
|---|
| 59 |
|
|---|
| 60 |
Founded = datetime.date(1835, 9, 13), |
|---|
| 61 |
Opens = datetime.time(9, 0, 0), |
|---|
| 62 |
Admission = 0, |
|---|
| 63 |
)['ID'] |
|---|
| 64 |
|
|---|
| 65 |
Zoo.insert(Name = u'Montr\xe9al Biod\xf4me', |
|---|
| 66 |
Founded = datetime.date(1992, 6, 19), |
|---|
| 67 |
Opens = datetime.time(9, 0, 0), |
|---|
| 68 |
Admission = 11.75, |
|---|
| 69 |
) |
|---|
| 70 |
|
|---|
| 71 |
seaworld = Zoo.insert(Name = 'Sea_World', Admission = 60)['ID'] |
|---|
| 72 |
|
|---|
| 73 |
|
|---|
| 74 |
lp = Zoo.insert(Name = 'Luna Park', |
|---|
| 75 |
Founded = datetime.date(2072, 7, 17), |
|---|
| 76 |
Opens = datetime.time(0, 0, 0), |
|---|
| 77 |
Admission = 134.95, |
|---|
| 78 |
)['ID'] |
|---|
| 79 |
|
|---|
| 80 |
|
|---|
| 81 |
leopardid = Animal.insert(Species='Leopard', Lifespan=73.5)['ID'] |
|---|
| 82 |
Animal.save(ID=leopardid, ZooID=wap, |
|---|
| 83 |
LastEscape=datetime.datetime(2004, 12, 21, 8, 15, 0, 999907)) |
|---|
| 84 |
|
|---|
| 85 |
lion = Animal.insert(Species='Lion', ZooID=wap)['ID'] |
|---|
| 86 |
Animal.insert(Species='Slug', Legs=1, Lifespan=.75) |
|---|
| 87 |
|
|---|
| 88 |
tiger = Animal.insert(Species='Tiger', ZooID=sdz)['ID'] |
|---|
| 89 |
|
|---|
| 90 |
|
|---|
| 91 |
Animal.insert(Species='Bear', Legs=4) |
|---|
| 92 |
Animal.insert(Species='Ostrich', Legs=2, Lifespan=103.2) |
|---|
| 93 |
Animal.insert(Species='Centipede', Legs=100) |
|---|
| 94 |
|
|---|
| 95 |
emp = Animal.insert(Species='Emperor Penguin', Legs=2, ZooID=seaworld)['ID'] |
|---|
| 96 |
adelie = Animal.insert(Species='Adelie Penguin', Legs=2, ZooID=seaworld)['ID'] |
|---|
| 97 |
|
|---|
| 98 |
Animal.insert(Species='Millipede', Legs=1000000, ZooID=sdz) |
|---|
| 99 |
|
|---|
| 100 |
|
|---|
| 101 |
bai_yun = Animal.insert(Species='Ape', Name='Bai Yun', Legs=2) |
|---|
| 102 |
Animal.insert(Species='Ape', Name='Hua Mei', Legs=2, MotherID=bai_yun['ID']) |
|---|
| 103 |
|
|---|
| 104 |
def step_2_insert(self): |
|---|
| 105 |
Animal = schema['Animal'] |
|---|
| 106 |
for x in xrange(ITERATIONS): |
|---|
| 107 |
tick = Animal.insert(Species='Tick', Name='Tick %d' % x, Legs=8) |
|---|
| 108 |
|
|---|
| 109 |
def step_3_Properties(self): |
|---|
| 110 |
Zoo = schema['Zoo'] |
|---|
| 111 |
Animal = schema['Animal'] |
|---|
| 112 |
|
|---|
| 113 |
for x in xrange(ITERATIONS): |
|---|
| 114 |
|
|---|
| 115 |
WAP = Zoo.select(Name='Wild Animal Park') |
|---|
| 116 |
SDZ = Zoo.select(Founded=datetime.date(1835, 9, 13)) |
|---|
| 117 |
Biodome = Zoo.select(Name=u'Montr\xe9al Biod\xf4me') |
|---|
| 118 |
seaworld = Zoo.select(lambda z: z.Admission == float(60)) |
|---|
| 119 |
|
|---|
| 120 |
|
|---|
| 121 |
leopard = Animal.select(lambda a: a.Species == 'Leopard') |
|---|
| 122 |
ostrich = Animal.select(Species='Ostrich') |
|---|
| 123 |
millipede = Animal.select(Legs=1000000) |
|---|
| 124 |
ticks = Animal.select(Species='Tick') |
|---|
| 125 |
|
|---|
| 126 |
def step_4_Expressions(self): |
|---|
| 127 |
Zoo = schema['Zoo'] |
|---|
| 128 |
Animal = schema['Animal'] |
|---|
| 129 |
|
|---|
| 130 |
for x in xrange(ITERATIONS): |
|---|
| 131 |
allzoos = Zoo.select_all() |
|---|
| 132 |
assert len(allzoos) == 5, allzoos |
|---|
| 133 |
assert len(Animal.select_all(lambda x: True)) == ITERATIONS + 12 |
|---|
| 134 |
assert len(Animal.select_all(lambda x: x.Legs == 4)) == 4 |
|---|
| 135 |
assert len(Animal.select_all(lambda x: x.Legs == 2)) == 5 |
|---|
| 136 |
assert len(Animal.select_all(lambda x: x.Legs >= 2 and x.Legs < 20)) == ITERATIONS + 9 |
|---|
| 137 |
assert len(Animal.select_all(lambda x: x.Legs > 10)) == 2 |
|---|
| 138 |
assert len(Animal.select_all(lambda x: x.Lifespan > 70)) == 2 |
|---|
| 139 |
assert len(Animal.select_all(lambda x: x.Species.startswith('L'))) == 2 |
|---|
| 140 |
assert len(Animal.select_all(lambda x: x.Species.endswith('pede'))) == 2 |
|---|
| 141 |
|
|---|
| 142 |
assert len(Animal.select_all(lambda x: x.LastEscape != None)) == 1 |
|---|
| 143 |
assert len(Animal.select_all(lambda x: None == x.LastEscape)) == ITERATIONS + 11 |
|---|
| 144 |
|
|---|
| 145 |
|
|---|
| 146 |
assert len(Animal.select_all(lambda x: 'pede' in x.Species)) == 2 |
|---|
| 147 |
assert len(Animal.select_all(lambda x: x.Species in ('Lion', 'Tiger', 'Bear'))) == 3 |
|---|
| 148 |
|
|---|
| 149 |
|
|---|
| 150 |
class thing(object): pass |
|---|
| 151 |
pet, pet2 = thing(), thing() |
|---|
| 152 |
pet.Name, pet2.Name = 'Slug', 'Ostrich' |
|---|
| 153 |
assert len(Animal.select_all(lambda x: x.Species in (pet.Name, pet2.Name))) == 2 |
|---|
| 154 |
|
|---|
| 155 |
|
|---|
| 156 |
assert len(Animal.select_all(lambda x: ieq(x.Species, 'slug'))) == 1 |
|---|
| 157 |
assert len(Animal.select_all(lambda x: icontains(x.Species, 'PEDE'))) == 2 |
|---|
| 158 |
name = 'Lion' |
|---|
| 159 |
assert len(Animal.select_all(lambda x: len(x.Species) == len(name))) == ITERATIONS + 3 |
|---|
| 160 |
|
|---|
| 161 |
|
|---|
| 162 |
assert len(Animal.select_all(lambda x: 'i' in x.Species)) == ITERATIONS + 7 |
|---|
| 163 |
|
|---|
| 164 |
|
|---|
| 165 |
assert len(Zoo.select_all(lambda x: x.Founded != None |
|---|
| 166 |
and x.Founded < today())) == 3 |
|---|
| 167 |
assert len(Animal.select_all(lambda x: x.LastEscape == now())) == 0 |
|---|
| 168 |
assert len(Animal.select_all(lambda x: year(x.LastEscape) == 2004)) == 1 |
|---|
| 169 |
assert len(Animal.select_all(lambda x: month(x.LastEscape) == 12)) == 1 |
|---|
| 170 |
assert len(Animal.select_all(lambda x: day(x.LastEscape) == 21)) == 1 |
|---|
| 171 |
|
|---|
| 172 |
def step_5_Aggregates(self): |
|---|
| 173 |
Animal = schema['Animal'] |
|---|
| 174 |
Zoo = schema['Zoo'] |
|---|
| 175 |
|
|---|
| 176 |
for x in xrange(ITERATIONS): |
|---|
| 177 |
|
|---|
| 178 |
legs = [l for l, in db.select((Animal, ['Legs']))] |
|---|
| 179 |
legs.sort() |
|---|
| 180 |
|
|---|
| 181 |
expected = {'Leopard': 73.5, |
|---|
| 182 |
'Slug': .75, |
|---|
| 183 |
'Tiger': None, |
|---|
| 184 |
'Lion': None, |
|---|
| 185 |
'Bear': None, |
|---|
| 186 |
'Ostrich': 103.2, |
|---|
| 187 |
'Centipede': None, |
|---|
| 188 |
'Emperor Penguin': None, |
|---|
| 189 |
'Adelie Penguin': None, |
|---|
| 190 |
'Millipede': None, |
|---|
| 191 |
'Ape': None, |
|---|
| 192 |
'Tick': None, |
|---|
| 193 |
} |
|---|
| 194 |
for species, lifespan in db.select((Animal, ['Species', 'Lifespan'])): |
|---|
| 195 |
assert lifespan == expected[species] |
|---|
| 196 |
|
|---|
| 197 |
expected = [u'Montr\xe9al Biod\xf4me', 'Wild Animal Park'] |
|---|
| 198 |
e = (lambda x: x.Founded != None |
|---|
| 199 |
and x.Founded <= today() |
|---|
| 200 |
and x.Founded >= datetime.date(1990, 1, 1)) |
|---|
| 201 |
values = [val[0] for val in |
|---|
| 202 |
db.select((Zoo, ['Name'], e))] |
|---|
| 203 |
assert set(values) == set(expected) |
|---|
| 204 |
|
|---|
| 205 |
|
|---|
| 206 |
legs = [x[0] for x in |
|---|
| 207 |
db.select((Animal, ['Legs']), distinct=True)] |
|---|
| 208 |
legs.sort() |
|---|
| 209 |
|
|---|
| 210 |
def step_6_Editing(self): |
|---|
| 211 |
Zoo = schema['Zoo'] |
|---|
| 212 |
|
|---|
| 213 |
for x in xrange(ITERATIONS): |
|---|
| 214 |
|
|---|
| 215 |
SDZ = Zoo.select(Name='San Diego Zoo') |
|---|
| 216 |
Zoo.save(ID=SDZ['ID'], |
|---|
| 217 |
Name='The San Diego Zoo', |
|---|
| 218 |
Founded = datetime.date(1900, 1, 1), |
|---|
| 219 |
Opens = datetime.time(7, 30, 0), |
|---|
| 220 |
Admission = "35.00") |
|---|
| 221 |
|
|---|
| 222 |
|
|---|
| 223 |
SDZ = Zoo.select(Name='The San Diego Zoo') |
|---|
| 224 |
assert SDZ['Founded'] == datetime.date(1900, 1, 1) |
|---|
| 225 |
|
|---|
| 226 |
|
|---|
| 227 |
Zoo.save(ID=SDZ['ID'], |
|---|
| 228 |
Name = 'San Diego Zoo', |
|---|
| 229 |
Founded = datetime.date(1835, 9, 13), |
|---|
| 230 |
Opens = datetime.time(9, 0, 0), |
|---|
| 231 |
Admission = "0") |
|---|
| 232 |
|
|---|
| 233 |
|
|---|
| 234 |
SDZ = Zoo.select(Name='San Diego Zoo') |
|---|
| 235 |
assert SDZ['Founded'] == datetime.date(1835, 9, 13) |
|---|
| 236 |
|
|---|
| 237 |
def step_7_Multiselect(self): |
|---|
| 238 |
Zoo = schema['Zoo'] |
|---|
| 239 |
Animal = schema['Animal'] |
|---|
| 240 |
|
|---|
| 241 |
for x in xrange(ITERATIONS): |
|---|
| 242 |
f = (lambda z, a: z.Name == 'San Diego Zoo') |
|---|
| 243 |
zooed_animals = list(db.select((Zoo & Animal, |
|---|
| 244 |
[('ID',), Animal.keys()], f))) |
|---|
| 245 |
|
|---|
| 246 |
SDZ = Zoo.select(Name='San Diego Zoo') |
|---|
| 247 |
|
|---|
| 248 |
sdexpr = logic.filter(Name='San Diego Zoo') |
|---|
| 249 |
leo = lambda z, a: a.Species == 'Leopard' |
|---|
| 250 |
zooed_animals = list(db.select((Zoo & Animal, |
|---|
| 251 |
[('ID',), ('ID', )], |
|---|
| 252 |
sdexpr + leo))) |
|---|
| 253 |
|
|---|
| 254 |
|
|---|
| 255 |
zooed_animals = list(db.select((Zoo & Animal, [('Name', ), ('Species', )]))) |
|---|
| 256 |
zooed_animals = list(db.select((Zoo >> Animal, [('Name', ), ('Species', )]))) |
|---|
| 257 |
zooed_animals = list(db.select((Zoo << Animal, [('Name', ), ('Species', )]))) |
|---|
| 258 |
|
|---|
| 259 |
|
|---|
| 260 |
db = None |
|---|
| 261 |
schema = None |
|---|
| 262 |
|
|---|
| 263 |
def run(provider, name, opts): |
|---|
| 264 |
global db, schema |
|---|
| 265 |
try: |
|---|
| 266 |
db = geniusql.db(provider, **opts) |
|---|
| 267 |
print db.version() |
|---|
| 268 |
db.create() |
|---|
| 269 |
schema = db.schema(name) |
|---|
| 270 |
schema.create() |
|---|
| 271 |
|
|---|
| 272 |
db.connections.implicit_trans = True |
|---|
| 273 |
|
|---|
| 274 |
zm = ZooMark() |
|---|
| 275 |
if profile: |
|---|
| 276 |
from cherrypy.lib import profiler |
|---|
| 277 |
p = profiler.Profiler(thisdir) |
|---|
| 278 |
for method in [x for x in dir(zm) if x.startswith("step_")]: |
|---|
| 279 |
startTime = datetime.datetime.now() |
|---|
| 280 |
meth = getattr(zm, method) |
|---|
| 281 |
if profile: |
|---|
| 282 |
p.run(meth) |
|---|
| 283 |
elif conquer: |
|---|
| 284 |
import pyconquer |
|---|
| 285 |
events = ['call', 'return', 'exception'] |
|---|
| 286 |
|
|---|
| 287 |
tr = pyconquer.Logger(events=events) |
|---|
| 288 |
tr.out = open(os.path.join(thisdir, "%s.log" % method), "wb") |
|---|
| 289 |
tr.time_calls = True |
|---|
| 290 |
try: |
|---|
| 291 |
tr.start() |
|---|
| 292 |
meth() |
|---|
| 293 |
finally: |
|---|
| 294 |
tr.stop() |
|---|
| 295 |
tr.out.close() |
|---|
| 296 |
else: |
|---|
| 297 |
meth() |
|---|
| 298 |
print "Ran %s in: %s" % (method, datetime.datetime.now() - startTime) |
|---|
| 299 |
finally: |
|---|
| 300 |
try: |
|---|
| 301 |
schema.drop_database() |
|---|
| 302 |
except (AttributeError, NotImplementedError): |
|---|
| 303 |
pass |
|---|
| 304 |
db.connections.shutdown() |
|---|
| 305 |
|
|---|
| 306 |
|
|---|
| 307 |
ITERATIONS = 100 |
|---|
| 308 |
|
|---|
| 309 |
if __name__ == '__main__': |
|---|
| 310 |
args = sys.argv[1:] |
|---|
| 311 |
if args: |
|---|
| 312 |
ITERATIONS = int(args[-1]) |
|---|
| 313 |
profile = "--profile" in args |
|---|
| 314 |
conquer = "--conquer" in args |
|---|
| 315 |
|
|---|
| 316 |
import getpass |
|---|
| 317 |
run("psycopg", "geniusql_bench", |
|---|
| 318 |
opts = {'connections.Connect': |
|---|
| 319 |
("host=localhost dbname=geniusql_bench user=postgres " |
|---|
| 320 |
"password=%s" % getpass.getpass("Postgres password:"))} |
|---|
| 321 |
) |
|---|
| 322 |
|
|---|