Benchmarks: Python 3 tweaks + more consistent testing of small vs big docs
This commit is contained in:
		| @@ -1,16 +1,11 @@ | ||||
| import unittest | ||||
| from timeit import repeat | ||||
|  | ||||
| import mongoengine | ||||
| from mongoengine import (BooleanField, Document, EmbeddedDocument, | ||||
| from mongoengine import (BooleanField, Document, EmailField, EmbeddedDocument, | ||||
|                          EmbeddedDocumentField, IntField, ListField, | ||||
|                          StringField) | ||||
|  | ||||
| conn_settings = { | ||||
|     'db': 'mongoengine-benchmark-test', | ||||
| } | ||||
|  | ||||
| mongoengine.connect(**conn_settings) | ||||
| mongoengine.connect(db='mongoengine_benchmark_test') | ||||
|  | ||||
|  | ||||
| def timeit(f, n=10000): | ||||
| @@ -23,6 +18,7 @@ def test_basic(): | ||||
|         pages = IntField() | ||||
|         tags = ListField(StringField()) | ||||
|         is_published = BooleanField() | ||||
|         author_email = EmailField() | ||||
|  | ||||
|     Book.drop_collection() | ||||
|  | ||||
| @@ -32,39 +28,57 @@ def test_basic(): | ||||
|             pages=100, | ||||
|             tags=['self-help', 'sales'], | ||||
|             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() | ||||
|     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' % ( | ||||
|         timeit(lambda: setattr(b, 'name', 'New name'), 10000) * 10**6 | ||||
|     print( | ||||
|         'Doc setattr: %.3fus' % ( | ||||
|             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(): | ||||
|         b._mark_as_changed('name') | ||||
|         b._mark_as_changed('tags') | ||||
|         b.save() | ||||
|  | ||||
|     save_book() | ||||
|     print('Save to database: %.3fus' % (timeit(save_book, 100) * 10**6)) | ||||
|  | ||||
|     son = b.to_mongo() | ||||
|  | ||||
|     print 'Load from SON: %.3fus' % ( | ||||
|         timeit(lambda: Book._from_son(son), 1000) * 10**6 | ||||
|     print( | ||||
|         'Load from SON: %.3fus' % ( | ||||
|             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' % ( | ||||
|             timeit(lambda: Book.objects[0], 100) * 10**6 | ||||
|         ) | ||||
|     ) | ||||
|  | ||||
|     print 'Load from database: %.3fus' % ( | ||||
|         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): | ||||
|         name = 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.save() | ||||
|         c.delete() | ||||
|  | ||||
|     print 'Save/delete big object to database: %.3fms' % ( | ||||
|         timeit(create_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 | ||||
|     print( | ||||
|         'Init + save to database + delete: %.3fms' % ( | ||||
|             timeit(create_and_delete_company, 10) * 10**3 | ||||
|         ) | ||||
|     ) | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     test_basic() | ||||
|     test_embedded() | ||||
|     print('-' * 100) | ||||
|     test_big_doc() | ||||
|   | ||||
| @@ -5,17 +5,17 @@ def main(): | ||||
|     setup = """ | ||||
| from pymongo import MongoClient | ||||
| connection = MongoClient() | ||||
| connection.drop_database('timeit_test') | ||||
| connection.drop_database('mongoengine_benchmark_test') | ||||
| """ | ||||
|  | ||||
|     stmt = """ | ||||
| from pymongo import MongoClient | ||||
| connection = MongoClient() | ||||
|  | ||||
| db = connection.timeit_test | ||||
| db = connection.mongoengine_benchmark_test | ||||
| noddy = db.noddy | ||||
|  | ||||
| for i in xrange(10000): | ||||
| for i in range(10000): | ||||
|     example = {'fields': {}} | ||||
|     for j in range(20): | ||||
|         example['fields']["key"+str(j)] = "value "+str(j) | ||||
| @@ -26,19 +26,19 @@ myNoddys = noddy.find() | ||||
| [n for n in myNoddys]  # iterate | ||||
| """ | ||||
|  | ||||
|     print "-" * 100 | ||||
|     print """Creating 10000 dictionaries - PyMongo""" | ||||
|     print('-' * 100) | ||||
|     print('PyMongo: Creating 10000 dictionaries.') | ||||
|     t = timeit.Timer(stmt=stmt, setup=setup) | ||||
|     print '{}s'.format(t.timeit(1)) | ||||
|     print('{}s'.format(t.timeit(1))) | ||||
|  | ||||
|     stmt = """ | ||||
| from pymongo import MongoClient, WriteConcern | ||||
| connection = MongoClient() | ||||
|  | ||||
| db = connection.timeit_test | ||||
| db = connection.mongoengine_benchmark_test | ||||
| noddy = db.noddy.with_options(write_concern=WriteConcern(w=0)) | ||||
|  | ||||
| for i in xrange(10000): | ||||
| for i in range(10000): | ||||
|     example = {'fields': {}} | ||||
|     for j in range(20): | ||||
|         example['fields']["key"+str(j)] = "value "+str(j) | ||||
| @@ -49,26 +49,26 @@ myNoddys = noddy.find() | ||||
| [n for n in myNoddys]  # iterate | ||||
| """ | ||||
|  | ||||
|     print "-" * 100 | ||||
|     print """Creating 10000 dictionaries - PyMongo write_concern={"w": 0}""" | ||||
|     print('-' * 100) | ||||
|     print('PyMongo: Creating 10000 dictionaries (write_concern={"w": 0}).') | ||||
|     t = timeit.Timer(stmt=stmt, setup=setup) | ||||
|     print '{}s'.format(t.timeit(1)) | ||||
|     print('{}s'.format(t.timeit(1))) | ||||
|  | ||||
|     setup = """ | ||||
| from pymongo import MongoClient | ||||
| connection = MongoClient() | ||||
| connection.drop_database('timeit_test') | ||||
| connection.drop_database('mongoengine_benchmark_test') | ||||
| connection.close() | ||||
|  | ||||
| from mongoengine import Document, DictField, connect | ||||
| connect("timeit_test") | ||||
| connect("mongoengine_benchmark_test") | ||||
|  | ||||
| class Noddy(Document): | ||||
|     fields = DictField() | ||||
| """ | ||||
|  | ||||
|     stmt = """ | ||||
| for i in xrange(10000): | ||||
| for i in range(10000): | ||||
|     noddy = Noddy() | ||||
|     for j in range(20): | ||||
|         noddy.fields["key"+str(j)] = "value "+str(j) | ||||
| @@ -78,13 +78,13 @@ myNoddys = Noddy.objects() | ||||
| [n for n in myNoddys]  # iterate | ||||
| """ | ||||
|  | ||||
|     print "-" * 100 | ||||
|     print "Creating 10000 dictionaries - MongoEngine" | ||||
|     print('-' * 100) | ||||
|     print('MongoEngine: Creating 10000 dictionaries.') | ||||
|     t = timeit.Timer(stmt=stmt, setup=setup) | ||||
|     print '{}s'.format(t.timeit(1)) | ||||
|     print('{}s'.format(t.timeit(1))) | ||||
|  | ||||
|     stmt = """ | ||||
| for i in xrange(10000): | ||||
| for i in range(10000): | ||||
|     noddy = Noddy() | ||||
|     fields = {} | ||||
|     for j in range(20): | ||||
| @@ -96,13 +96,13 @@ myNoddys = Noddy.objects() | ||||
| [n for n in myNoddys]  # iterate | ||||
| """ | ||||
|  | ||||
|     print "-" * 100 | ||||
|     print "Creating 10000 dictionaries without continual assign - MongoEngine" | ||||
|     print('-' * 100) | ||||
|     print('MongoEngine: Creating 10000 dictionaries (using a single field assignment).') | ||||
|     t = timeit.Timer(stmt=stmt, setup=setup) | ||||
|     print '{}s'.format(t.timeit(1)) | ||||
|     print('{}s'.format(t.timeit(1))) | ||||
|  | ||||
|     stmt = """ | ||||
| for i in xrange(10000): | ||||
| for i in range(10000): | ||||
|     noddy = Noddy() | ||||
|     for j in range(20): | ||||
|         noddy.fields["key"+str(j)] = "value "+str(j) | ||||
| @@ -112,13 +112,13 @@ myNoddys = Noddy.objects() | ||||
| [n for n in myNoddys] # iterate | ||||
| """ | ||||
|  | ||||
|     print "-" * 100 | ||||
|     print """Creating 10000 dictionaries - MongoEngine - write_concern={"w": 0}""" | ||||
|     print('-' * 100) | ||||
|     print('MongoEngine: Creating 10000 dictionaries (write_concern={"w": 0}).') | ||||
|     t = timeit.Timer(stmt=stmt, setup=setup) | ||||
|     print '{}s'.format(t.timeit(1)) | ||||
|     print('{}s'.format(t.timeit(1))) | ||||
|  | ||||
|     stmt = """ | ||||
| for i in xrange(10000): | ||||
| for i in range(10000): | ||||
|     noddy = Noddy() | ||||
|     for j in range(20): | ||||
|         noddy.fields["key"+str(j)] = "value "+str(j) | ||||
| @@ -128,13 +128,13 @@ myNoddys = Noddy.objects() | ||||
| [n for n in myNoddys] # iterate | ||||
| """ | ||||
|  | ||||
|     print "-" * 100 | ||||
|     print """Creating 10000 dictionaries - MongoEngine, write_concern={"w": 0}, validate=False""" | ||||
|     print('-' * 100) | ||||
|     print('MongoEngine: Creating 10000 dictionaries (write_concern={"w": 0}, validate=False).') | ||||
|     t = timeit.Timer(stmt=stmt, setup=setup) | ||||
|     print '{}s'.format(t.timeit(1)) | ||||
|     print('{}s'.format(t.timeit(1))) | ||||
|  | ||||
|     stmt = """ | ||||
| for i in xrange(10000): | ||||
| for i in range(10000): | ||||
|     noddy = Noddy() | ||||
|     for j in range(20): | ||||
|         noddy.fields["key"+str(j)] = "value "+str(j) | ||||
| @@ -144,10 +144,10 @@ myNoddys = Noddy.objects() | ||||
| [n for n in myNoddys] # iterate | ||||
| """ | ||||
|  | ||||
|     print "-" * 100 | ||||
|     print """Creating 10000 dictionaries - MongoEngine, force_insert=True, write_concern={"w": 0}, validate=False""" | ||||
|     print('-' * 100) | ||||
|     print('MongoEngine: Creating 10000 dictionaries (force_insert=True, write_concern={"w": 0}, validate=False).') | ||||
|     t = timeit.Timer(stmt=stmt, setup=setup) | ||||
|     print '{}s'.format(t.timeit(1)) | ||||
|     print('{}s'.format(t.timeit(1))) | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|   | ||||
		Reference in New Issue
	
	Block a user