[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