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

Tres Seaver <[email protected]>
Newsgroups gmane.comp.web.zope.devel
Message-ID <[email protected]>
-----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          [email protected]
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  -  [email protected]
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 )
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.