[Zope-dev] SVN: Zope/trunk/ Optimized the `OFS.Traversable.getPhysicalPath` method to avoid excessive amounts of method calls. Thx to Nikolay Kim from Enfold

Tres Seaver tseaver at palladion.com
Thu Jul 14 11:47:20 EDT 2011


-----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          tseaver at 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-----



More information about the Zope-Dev mailing list