-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 07/14/2011 04:16 AM, Hanno Schlichting wrote: > Log message for revision 122213: Optimized the > `OFS.Traversable.getPhysicalPath` method to avoid excessive amounts > of method calls. Thx to Nikolay Kim from Enfold > > > Changed: U Zope/trunk/doc/CHANGES.rst U > Zope/trunk/src/OFS/Traversable.py > > -=- Modified: Zope/trunk/doc/CHANGES.rst > =================================================================== > --- Zope/trunk/doc/CHANGES.rst 2011-07-14 07:16:04 UTC (rev 122212) > +++ Zope/trunk/doc/CHANGES.rst 2011-07-14 08:16:08 UTC (rev 122213) > @@ -19,6 +19,9 @@ Features Added ++++++++++++++ > > +- Optimized the `OFS.Traversable.getPhysicalPath` method to avoid > excessive + amounts of method calls. + - During startup open a > connection to every configured database, to ensure all of them can > indeed be accessed. This avoids surprises during runtime when > traversal to some database mountpoint could fail as the underlying > storage > > Modified: Zope/trunk/src/OFS/Traversable.py > =================================================================== > --- Zope/trunk/src/OFS/Traversable.py 2011-07-14 07:16:04 UTC (rev > 122212) +++ Zope/trunk/src/OFS/Traversable.py 2011-07-14 08:16:08 UTC > (rev 122213) @@ -114,14 +114,47 @@ access this object again later, > for example in a copy/paste operation. getPhysicalRoot() and > getPhysicalPath() are designed to operate together. + + This > implementation is optimized to avoid excessive amounts of function + > calls while walking up from an object on a deep level. """ - > path = (self.getId(),) + try: + id = self.id + > except AttributeError: + id = self.getId() + else: > + if id is None: + id = self.getId() > > p = aq_parent(aq_inner(self)) + if p is None: + > return (id, ) > > - if p is not None: - path = p.getPhysicalPath() + > path + path = [id] + func = > self.getPhysicalPath.im_func + while p is not None: + > if func is p.getPhysicalPath.im_func: + try: + > pid = p.id + except AttributeError: + > pid = p.getId() + else: + if pid is > None: + pid = p.getId() > > + path.insert(0, pid) + try: + > p = p.__parent__ + except AttributeError: + > p = None + else: + if > IApplication.providedBy(p): + path.insert(0, '') + > path = tuple(path) + else: + path = > p.getPhysicalPath() + tuple(path) + break + return > path > > security.declarePrivate('unrestrictedTraverse')
While we're at it, 'list.insert(0,foo)' is known to be slower in a tight loop than 'list.append(foo)', with a 'reversed' at the end of the loop:: $ python -m timeit -s "from string import letters" "path = []" \ "for letter in letters: path.append(letter)" \ "result = tuple(reversed(path))" 100000 loops, best of 3: 15.9 usec per loop $ python -m timeit -s "from string import letters" "path = []" \ "for letter in letters: path.insert(0, letter)" \ "result = tuple(path)" 10000 loops, best of 3: 25.3 usec per loop For the sake of comparison, the original tuple addition is actually between the two: $ python -m timeit -s "from string import letters" "result = ()" \ "for letter in letters: result += (letter,)" 10000 loops, best of 3: 21.6 usec per loop Tres. - -- =================================================================== Tres Seaver +1 540-429-0999 tsea...@palladion.com Palladion Software "Excellence by Design" http://palladion.com -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk4fD4gACgkQ+gerLs4ltQ7b3QCg1z+oZKKDZ5IhuMvAockJ9mvx SO4AoIr3IEMnq78m70DZAOc0yV9+++y4 =8vOY -----END PGP SIGNATURE----- _______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org https://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - https://mail.zope.org/mailman/listinfo/zope-announce https://mail.zope.org/mailman/listinfo/zope )