[Checkins] SVN: mongopersist/trunk/ - Performance: Improved the profiler a bit by allowing to disable modification

Stephen Richter cvs-admin at zope.org
Fri Apr 13 13:26:20 UTC 2012


Log message for revision 125134:
  - Performance: Improved the profiler a bit by allowing to disable modification
    of records as well.
  
  - Performance: Added caching of ``_m_jar`` lookups in Mongo Containers, since
    the computation turned out to be significantly expensive.
  
  - Performance: Use lazy hash computation for DBRef. Also, disable support for
    arbitrary keyword arguments. This makes roughly a 2-4% difference in object
    loading time.
  
  Get ready for release.
  
  

Changed:
  U   mongopersist/trunk/CHANGES.txt
  U   mongopersist/trunk/setup.py
  U   mongopersist/trunk/src/mongopersist/performance.py
  U   mongopersist/trunk/src/mongopersist/zope/container.py

-=-
Modified: mongopersist/trunk/CHANGES.txt
===================================================================
--- mongopersist/trunk/CHANGES.txt	2012-04-13 08:51:15 UTC (rev 125133)
+++ mongopersist/trunk/CHANGES.txt	2012-04-13 13:26:16 UTC (rev 125134)
@@ -2,11 +2,23 @@
 CHANGES
 =======
 
-0.7.1 (2012-04-??)
+0.7.1 (2012-04-13)
 ------------------
 
-- Bug: don't err on missing _py_serial on older states from mongo
+- Performance: Improved the profiler a bit by allowing to disable modification
+  of records as well.
 
+- Performance: Added caching of ``_m_jar`` lookups in Mongo Containers, since
+  the computation turned out to be significantly expensive.
+
+- Performance: Use lazy hash computation for DBRef. Also, disable support for
+  arbitrary keyword arguments. This makes roughly a 2-4% difference in object
+  loading time.
+
+- Bug: An error occurred when ``_py_serial`` was missing. This was 
+  possible due to a bug in version 0.6. It also protects against third 
+  party software which is not aware of our meta-data.
+
 - Performance: Switched to ``repoze.lru`` (from ``lru``), which is much
   faster.
 

Modified: mongopersist/trunk/setup.py
===================================================================
--- mongopersist/trunk/setup.py	2012-04-13 08:51:15 UTC (rev 125133)
+++ mongopersist/trunk/setup.py	2012-04-13 13:26:16 UTC (rev 125134)
@@ -9,7 +9,7 @@
 
 setup (
     name='mongopersist',
-    version='0.7.1.dev0',
+    version='0.7.1',
     author = "Stephan Richter",
     author_email = "stephan.richter at gmail.com",
     description = "Mongo Persistence Backend",

Modified: mongopersist/trunk/src/mongopersist/performance.py
===================================================================
--- mongopersist/trunk/src/mongopersist/performance.py	2012-04-13 08:51:15 UTC (rev 125133)
+++ mongopersist/trunk/src/mongopersist/performance.py	2012-04-13 13:26:16 UTC (rev 125134)
@@ -28,11 +28,18 @@
 
 MULTIPLE_CLASSES = True
 
+
 class People(container.AllItemsMongoContainer):
     _p_mongo_collection = 'people'
     _m_database = 'performance'
     _m_collection = 'person'
 
+class Address(persistent.Persistent):
+    _p_mongo_collection = 'address'
+
+    def __init__(self, city):
+        self.city = city
+
 class Person(persistent.Persistent, container.MongoContained):
     _p_mongo_collection = 'person'
     _p_mongo_store_type = True
@@ -40,6 +47,7 @@
     def __init__(self, name, age):
         self.name = name
         self.age = age
+        self.address = Address('Boston %i' %age)
 
     def __repr__(self):
         return '<%s %s @ %i [%s]>' %(
@@ -48,7 +56,6 @@
 class Person2(Person):
     pass
 
-
 def run_basic_crud(options):
     conn = pymongo.Connection('localhost', 27017, tz_aware=False)
     dm = datamanager.MongoDataManager(
@@ -73,68 +80,49 @@
     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 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 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
+    # Profile fast read (values)
     transaction.begin()
     t1 = time.time()
-    [person.name for person in people.find()]
+    [person.name for person in people.values()]
     #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)
+    print 'Fast Read (values): %.4f secs' % (t2-t1)
 
-    # Profile fast read (cache)
+    # Profile fast read
     transaction.begin()
     t1 = time.time()
-    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()
+    [person.name for person in people.find()]
+    #cProfile.runctx(
+    #    '[person.name for person in people.find()]', globals(), locals())
     t2 = time.time()
     transaction.commit()
-    print 'Fast Read (cache):  %.4f secs' % (t2-t1)
+    print 'Fast Read (find):   %.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.modify:
+        # 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
@@ -159,6 +147,11 @@
     help='A flag, when set, causes the DB not to be reloaded.')
 
 parser.add_option(
+    '--no-modify', action='store_false',
+    dest='modify', default=True,
+    help='A flag, when set, causes the data not to be modified.')
+
+parser.add_option(
     '--no-delete', action='store_false',
     dest='delete', default=True,
     help='A flag, when set, causes the data not to be deleted at the end.')

Modified: mongopersist/trunk/src/mongopersist/zope/container.py
===================================================================
--- mongopersist/trunk/src/mongopersist/zope/container.py	2012-04-13 08:51:15 UTC (rev 125133)
+++ mongopersist/trunk/src/mongopersist/zope/container.py	2012-04-13 13:26:16 UTC (rev 125134)
@@ -118,14 +118,16 @@
 
     @property
     def _m_jar(self):
-        # If the container is in a Mongo storage hierarchy, then getting the
-        # datamanager is easy, otherwise we do an adapter lookup.
-        if interfaces.IMongoDataManager.providedBy(self._p_jar):
-            return self._p_jar
-        else:
-            provider = zope.component.getUtility(
-                interfaces.IMongoDataManagerProvider)
-            return provider.get()
+        if not hasattr(self, '_v_m_jar'):
+            # If the container is in a Mongo storage hierarchy, then getting
+            # the datamanager is easy, otherwise we do an adapter lookup.
+            if interfaces.IMongoDataManager.providedBy(self._p_jar):
+                self._v_m_jar = self._p_jar
+            else:
+                provider = zope.component.getUtility(
+                    interfaces.IMongoDataManagerProvider)
+                self._v_m_jar = provider.get()
+        return self._v_m_jar
 
     def get_collection(self):
         db_name = self._m_database or self._m_jar.default_database



More information about the checkins mailing list