Benchmarks: Python 3 tweaks + more consistent testing of small vs big docs

This commit is contained in:
Stefan Wojcik 2019-06-17 09:31:51 +02:00
parent 97005aca66
commit 6527b1386f
2 changed files with 101 additions and 65 deletions

View File

@ -1,16 +1,11 @@
import unittest
from timeit import repeat from timeit import repeat
import mongoengine import mongoengine
from mongoengine import (BooleanField, Document, EmbeddedDocument, from mongoengine import (BooleanField, Document, EmailField, EmbeddedDocument,
EmbeddedDocumentField, IntField, ListField, EmbeddedDocumentField, IntField, ListField,
StringField) StringField)
conn_settings = { mongoengine.connect(db='mongoengine_benchmark_test')
'db': 'mongoengine-benchmark-test',
}
mongoengine.connect(**conn_settings)
def timeit(f, n=10000): def timeit(f, n=10000):
@ -23,6 +18,7 @@ def test_basic():
pages = IntField() pages = IntField()
tags = ListField(StringField()) tags = ListField(StringField())
is_published = BooleanField() is_published = BooleanField()
author_email = EmailField()
Book.drop_collection() Book.drop_collection()
@ -32,39 +28,57 @@ def test_basic():
pages=100, pages=100,
tags=['self-help', 'sales'], tags=['self-help', 'sales'],
is_published=True, is_published=True,
author_email='alec@example.com',
) )
print 'Doc initialization: %.3fus' % (timeit(init_book, 1000) * 10**6) print('Doc initialization: %.3fus' % (timeit(init_book, 1000) * 10**6))
b = init_book() b = init_book()
print 'Doc getattr: %.3fus' % (timeit(lambda: b.name, 10000) * 10**6) print('Doc getattr: %.3fus' % (timeit(lambda: b.name, 10000) * 10**6))
print 'Doc setattr: %.3fus' % ( print(
'Doc setattr: %.3fus' % (
timeit(lambda: setattr(b, 'name', 'New name'), 10000) * 10**6 timeit(lambda: setattr(b, 'name', 'New name'), 10000) * 10**6
) )
)
print 'Doc to mongo: %.3fus' % (timeit(b.to_mongo, 1000) * 10**6) print('Doc to mongo: %.3fus' % (timeit(b.to_mongo, 1000) * 10**6))
print('Doc validation: %.3fus' % (timeit(b.validate, 1000) * 10**6))
def save_book(): def save_book():
b._mark_as_changed('name') b._mark_as_changed('name')
b._mark_as_changed('tags') b._mark_as_changed('tags')
b.save() b.save()
save_book() print('Save to database: %.3fus' % (timeit(save_book, 100) * 10**6))
son = b.to_mongo()
print 'Load from SON: %.3fus' % ( son = b.to_mongo()
print(
'Load from SON: %.3fus' % (
timeit(lambda: Book._from_son(son), 1000) * 10**6 timeit(lambda: Book._from_son(son), 1000) * 10**6
) )
)
print 'Save to database: %.3fus' % (timeit(save_book, 100) * 10**6) print(
'Load from database: %.3fus' % (
print 'Load from database: %.3fus' % (
timeit(lambda: Book.objects[0], 100) * 10**6 timeit(lambda: Book.objects[0], 100) * 10**6
) )
)
def create_and_delete_book():
b = init_book()
b.save()
b.delete()
print(
'Init + save to database + delete: %.3fms' % (
timeit(create_and_delete_book, 10) * 10**3
)
)
def test_embedded(): def test_big_doc():
class Contact(EmbeddedDocument): class Contact(EmbeddedDocument):
name = StringField() name = StringField()
title = StringField() title = StringField()
@ -89,24 +103,46 @@ def test_embedded():
] ]
) )
def create_company(): company = init_company()
print('Big doc to mongo: %.3fms' % (timeit(company.to_mongo, 100) * 10**3))
print('Big doc validation: %.3fms' % (timeit(company.validate, 1000) * 10**3))
company.save()
def save_company():
company._mark_as_changed('name')
company._mark_as_changed('contacts')
company.save()
print('Save to database: %.3fms' % (timeit(save_company, 100) * 10**3))
son = company.to_mongo()
print(
'Load from SON: %.3fms' % (
timeit(lambda: Company._from_son(son), 100) * 10**3
)
)
print(
'Load from database: %.3fms' % (
timeit(lambda: Company.objects[0], 100) * 10**3
)
)
def create_and_delete_company():
c = init_company() c = init_company()
c.save() c.save()
c.delete() c.delete()
print 'Save/delete big object to database: %.3fms' % ( print(
timeit(create_company, 10) * 10**3 'Init + save to database + delete: %.3fms' % (
timeit(create_and_delete_company, 10) * 10**3
) )
c = init_company().save()
print 'Serialize big object: %.3fms' % (
timeit(c.to_mongo, 100) * 10**3
)
print 'Load big object from database: %.3fms' % (
timeit(lambda: Company.objects[0], 100) * 10**3
) )
if __name__ == '__main__': if __name__ == '__main__':
test_basic() test_basic()
test_embedded() print('-' * 100)
test_big_doc()

View File

@ -5,17 +5,17 @@ def main():
setup = """ setup = """
from pymongo import MongoClient from pymongo import MongoClient
connection = MongoClient() connection = MongoClient()
connection.drop_database('timeit_test') connection.drop_database('mongoengine_benchmark_test')
""" """
stmt = """ stmt = """
from pymongo import MongoClient from pymongo import MongoClient
connection = MongoClient() connection = MongoClient()
db = connection.timeit_test db = connection.mongoengine_benchmark_test
noddy = db.noddy noddy = db.noddy
for i in xrange(10000): for i in range(10000):
example = {'fields': {}} example = {'fields': {}}
for j in range(20): for j in range(20):
example['fields']["key"+str(j)] = "value "+str(j) example['fields']["key"+str(j)] = "value "+str(j)
@ -26,19 +26,19 @@ myNoddys = noddy.find()
[n for n in myNoddys] # iterate [n for n in myNoddys] # iterate
""" """
print "-" * 100 print('-' * 100)
print """Creating 10000 dictionaries - PyMongo""" print('PyMongo: Creating 10000 dictionaries.')
t = timeit.Timer(stmt=stmt, setup=setup) t = timeit.Timer(stmt=stmt, setup=setup)
print '{}s'.format(t.timeit(1)) print('{}s'.format(t.timeit(1)))
stmt = """ stmt = """
from pymongo import MongoClient, WriteConcern from pymongo import MongoClient, WriteConcern
connection = MongoClient() connection = MongoClient()
db = connection.timeit_test db = connection.mongoengine_benchmark_test
noddy = db.noddy.with_options(write_concern=WriteConcern(w=0)) noddy = db.noddy.with_options(write_concern=WriteConcern(w=0))
for i in xrange(10000): for i in range(10000):
example = {'fields': {}} example = {'fields': {}}
for j in range(20): for j in range(20):
example['fields']["key"+str(j)] = "value "+str(j) example['fields']["key"+str(j)] = "value "+str(j)
@ -49,26 +49,26 @@ myNoddys = noddy.find()
[n for n in myNoddys] # iterate [n for n in myNoddys] # iterate
""" """
print "-" * 100 print('-' * 100)
print """Creating 10000 dictionaries - PyMongo write_concern={"w": 0}""" print('PyMongo: Creating 10000 dictionaries (write_concern={"w": 0}).')
t = timeit.Timer(stmt=stmt, setup=setup) t = timeit.Timer(stmt=stmt, setup=setup)
print '{}s'.format(t.timeit(1)) print('{}s'.format(t.timeit(1)))
setup = """ setup = """
from pymongo import MongoClient from pymongo import MongoClient
connection = MongoClient() connection = MongoClient()
connection.drop_database('timeit_test') connection.drop_database('mongoengine_benchmark_test')
connection.close() connection.close()
from mongoengine import Document, DictField, connect from mongoengine import Document, DictField, connect
connect("timeit_test") connect("mongoengine_benchmark_test")
class Noddy(Document): class Noddy(Document):
fields = DictField() fields = DictField()
""" """
stmt = """ stmt = """
for i in xrange(10000): for i in range(10000):
noddy = Noddy() noddy = Noddy()
for j in range(20): for j in range(20):
noddy.fields["key"+str(j)] = "value "+str(j) noddy.fields["key"+str(j)] = "value "+str(j)
@ -78,13 +78,13 @@ myNoddys = Noddy.objects()
[n for n in myNoddys] # iterate [n for n in myNoddys] # iterate
""" """
print "-" * 100 print('-' * 100)
print "Creating 10000 dictionaries - MongoEngine" print('MongoEngine: Creating 10000 dictionaries.')
t = timeit.Timer(stmt=stmt, setup=setup) t = timeit.Timer(stmt=stmt, setup=setup)
print '{}s'.format(t.timeit(1)) print('{}s'.format(t.timeit(1)))
stmt = """ stmt = """
for i in xrange(10000): for i in range(10000):
noddy = Noddy() noddy = Noddy()
fields = {} fields = {}
for j in range(20): for j in range(20):
@ -96,13 +96,13 @@ myNoddys = Noddy.objects()
[n for n in myNoddys] # iterate [n for n in myNoddys] # iterate
""" """
print "-" * 100 print('-' * 100)
print "Creating 10000 dictionaries without continual assign - MongoEngine" print('MongoEngine: Creating 10000 dictionaries (using a single field assignment).')
t = timeit.Timer(stmt=stmt, setup=setup) t = timeit.Timer(stmt=stmt, setup=setup)
print '{}s'.format(t.timeit(1)) print('{}s'.format(t.timeit(1)))
stmt = """ stmt = """
for i in xrange(10000): for i in range(10000):
noddy = Noddy() noddy = Noddy()
for j in range(20): for j in range(20):
noddy.fields["key"+str(j)] = "value "+str(j) noddy.fields["key"+str(j)] = "value "+str(j)
@ -112,13 +112,13 @@ myNoddys = Noddy.objects()
[n for n in myNoddys] # iterate [n for n in myNoddys] # iterate
""" """
print "-" * 100 print('-' * 100)
print """Creating 10000 dictionaries - MongoEngine - write_concern={"w": 0}""" print('MongoEngine: Creating 10000 dictionaries (write_concern={"w": 0}).')
t = timeit.Timer(stmt=stmt, setup=setup) t = timeit.Timer(stmt=stmt, setup=setup)
print '{}s'.format(t.timeit(1)) print('{}s'.format(t.timeit(1)))
stmt = """ stmt = """
for i in xrange(10000): for i in range(10000):
noddy = Noddy() noddy = Noddy()
for j in range(20): for j in range(20):
noddy.fields["key"+str(j)] = "value "+str(j) noddy.fields["key"+str(j)] = "value "+str(j)
@ -128,13 +128,13 @@ myNoddys = Noddy.objects()
[n for n in myNoddys] # iterate [n for n in myNoddys] # iterate
""" """
print "-" * 100 print('-' * 100)
print """Creating 10000 dictionaries - MongoEngine, write_concern={"w": 0}, validate=False""" print('MongoEngine: Creating 10000 dictionaries (write_concern={"w": 0}, validate=False).')
t = timeit.Timer(stmt=stmt, setup=setup) t = timeit.Timer(stmt=stmt, setup=setup)
print '{}s'.format(t.timeit(1)) print('{}s'.format(t.timeit(1)))
stmt = """ stmt = """
for i in xrange(10000): for i in range(10000):
noddy = Noddy() noddy = Noddy()
for j in range(20): for j in range(20):
noddy.fields["key"+str(j)] = "value "+str(j) noddy.fields["key"+str(j)] = "value "+str(j)
@ -144,10 +144,10 @@ myNoddys = Noddy.objects()
[n for n in myNoddys] # iterate [n for n in myNoddys] # iterate
""" """
print "-" * 100 print('-' * 100)
print """Creating 10000 dictionaries - MongoEngine, force_insert=True, write_concern={"w": 0}, validate=False""" print('MongoEngine: Creating 10000 dictionaries (force_insert=True, write_concern={"w": 0}, validate=False).')
t = timeit.Timer(stmt=stmt, setup=setup) t = timeit.Timer(stmt=stmt, setup=setup)
print '{}s'.format(t.timeit(1)) print('{}s'.format(t.timeit(1)))
if __name__ == "__main__": if __name__ == "__main__":