[Checkins] SVN: mongopersist/trunk/src/mongopersist/ * Overwrite some methods that UserDict just implements inefficiently.
Stephen Richter
cvs-admin at zope.org
Tue Apr 3 18:22:51 UTC 2012
Log message for revision 124923:
* Overwrite some methods that UserDict just implements inefficiently.
This gave me an 8-10% improvement in my performance tests.
* Added a hook for doing a proper object cache later.
Changed:
U mongopersist/trunk/src/mongopersist/performance.py
U mongopersist/trunk/src/mongopersist/serialize.py
-=-
Modified: mongopersist/trunk/src/mongopersist/performance.py
===================================================================
--- mongopersist/trunk/src/mongopersist/performance.py 2012-04-03 18:20:33 UTC (rev 124922)
+++ mongopersist/trunk/src/mongopersist/performance.py 2012-04-03 18:22:47 UTC (rev 124923)
@@ -12,6 +12,7 @@
#
##############################################################################
"""Mongo Persistence Performance Test"""
+from __future__ import absolute_import
import optparse
import persistent
import pymongo
@@ -72,25 +73,26 @@
else:
people = dm.root['people']
- # Profile slow read
- transaction.begin()
- t1 = time.time()
- [people[name].name for name in people]
- #cProfile.runctx(
- # '[people[name].name for name in people]', globals(), locals())
- t2 = time.time()
- transaction.commit()
- print 'Slow Read: %.4f secs' % (t2-t1)
+# # Profile slow read
+# transaction.begin()
+# t1 = time.time()
+# [people[name].name for name in people]
+# #cProfile.runctx(
+# # '[people[name].name for name in people]', globals(), locals())
+# t2 = time.time()
+# transaction.commit()
+# print 'Slow Read: %.4f secs' % (t2-t1)
+#
+# # Profile fast read (values)
+# transaction.begin()
+# t1 = time.time()
+# [person.name for person in people.values()]
+# #cProfile.runctx(
+# # '[person.name for person in people.find()]', globals(), locals())
+# t2 = time.time()
+# transaction.commit()
+# print 'Fast Read (values): %.4f secs' % (t2-t1)
- # Profile fast read (values)
- transaction.begin()
- t1 = time.time()
- [person.name for person in people.values()]
- #cProfile.runctx(
- # '[person.name for person in people.find()]', globals(), locals())
- t2 = time.time()
- print 'Fast Read (values): %.4f secs' % (t2-t1)
-
# Profile fast read
transaction.begin()
t1 = time.time()
@@ -98,21 +100,42 @@
#cProfile.runctx(
# '[person.name for person in people.find()]', globals(), locals())
t2 = time.time()
+ cache = [
+ (person.__class__,
+ people._p_oid,
+ people._p_jar._writer.get_full_state(person),
+ )
+ for person in people.values()]
+ transaction.commit()
print 'Fast Read (find): %.4f secs' % (t2-t1)
- # Profile modification
+ # Profile fast read (cache)
+ transaction.begin()
t1 = time.time()
- def modify():
- for person in list(people.find()):
- person.name += 'X'
- person.age += 1
- transaction.commit()
- modify()
- #cProfile.runctx(
- # 'modify()', globals(), locals())
+ def read():
+ for klass, dbref, doc in cache:
+ person = people._p_jar._reader.get_ghost(dbref, klass)
+ people._p_jar._reader.set_ghost_state(person, doc)
+ person.name
+ cProfile.runctx('read()', globals(), locals())
+ #read()
t2 = time.time()
- print 'Modification: %.4f secs' % (t2-t1)
+ transaction.commit()
+ print 'Fast Read (cache): %.4f secs' % (t2-t1)
+# # Profile modification
+# t1 = time.time()
+# def modify():
+# for person in list(people.find()):
+# person.name += 'X'
+# person.age += 1
+# transaction.commit()
+# modify()
+# #cProfile.runctx(
+# # 'modify()', globals(), locals())
+# t2 = time.time()
+# print 'Modification: %.4f secs' % (t2-t1)
+
if options.delete:
# Profile deletion
t1 = time.time()
Modified: mongopersist/trunk/src/mongopersist/serialize.py
===================================================================
--- mongopersist/trunk/src/mongopersist/serialize.py 2012-04-03 18:20:33 UTC (rev 124922)
+++ mongopersist/trunk/src/mongopersist/serialize.py 2012-04-03 18:22:47 UTC (rev 124923)
@@ -43,6 +43,26 @@
class PersistentDict(persistent.dict.PersistentDict):
_p_mongo_sub_object = True
+ def __init__(self, data=None, **kwargs):
+ # We optimize the case where data is not a dict. The original
+ # implementation always created an empty dict, which it then
+ # updated. This turned out to be expensive.
+ if data is None:
+ self.data = {}
+ elif isinstance(data, dict):
+ self.data = data.copy()
+ else:
+ self.data = dict(data)
+ if len(kwargs):
+ self.update(kwargs)
+
+ def __getitem__(self, key):
+ # The UserDict supports a __missing__() function, which I have never
+ # seen or used before, but it makes the method significantly
+ # slower. So let's not do that.
+ return self.data[key]
+
+
class PersistentList(persistent.list.PersistentList):
_p_mongo_sub_object = True
@@ -513,13 +533,14 @@
# Set the state.
obj.__setstate__(state)
- def get_ghost(self, dbref):
+ def get_ghost(self, dbref, klass=None):
# If we can, we return the object from cache.
try:
return self._jar._object_cache[dbref.id]
except KeyError:
pass
- klass = self.resolve(dbref)
+ if klass is None:
+ klass = self.resolve(dbref)
obj = klass.__new__(klass)
obj._p_jar = self._jar
obj._p_oid = dbref
More information about the checkins
mailing list