Hi!

This post has two purposes: An advertisement for trac ticket #11342,
and a technical question about a trick used in that ticket.

First, the question.

Usually, an error is raised with an error message. And thus, the cdef
function sage.structure.parent.raise_attribute_error(P,name)  first
creates a nice message stating that P does not have the attribute of
the given name.

But the typical fate of an attribute error is being caught. Hence,
normally, nobody will ever see the error message, and it is a waste of
time to create it in the first place.

One of the tricks that I use in #11342 to generally speed up getattr
of parents and elements is to introduce a new class
AttributeErrorMessage. It simply stores the class of P and the given
attribute name. Its string representation is the error message, and it
will *only* be created when requested (hence, not during
initialisation and not if the error is simply caught).

It seems to me that
   raise_attribute_error(P,name)
and
   raise AttributeError, AttributeErrorMessage(P,name)
do essentially the same - at least what appears on the screen is the
same, and the doctests seem to pass.

Question to Python experts: Are there pitfalls that I should take into
account?

Now, for the advertisement. Some timings.

sage: a = 1

# non-existing private attributes
sage: timeit('try: QQ.__bla\nexcept: pass')
625 loops, best of 3: 10.5 µs per loop
# unpatched: 13.8 µs
sage: timeit('try: a.__bla\nexcept: pass')
625 loops, best of 3: 8.78 µs per loop
# unpatched: 13.3 µs

# non-existing non-private attributes
sage: timeit('try: QQ.__bla_\nexcept: pass')
625 loops, best of 3: 14.1 µs per loop
# unpatched: 23.4 µs
sage: timeit('try: a.__bla_\nexcept: pass')
625 loops, best of 3: 16.1 µs per loop
# unpatched: 28.2 µs
sage: timeit('try: QQ.bla\nexcept: pass')
625 loops, best of 3: 13.8 µs per loop
# unpatched: 22.9 µs
sage: timeit('try: a.bla\nexcept: pass')
625 loops, best of 3: 16.3 µs per loop
# unpatched: 27.2 µs

# attributes inherited from the category
sage: timeit('try: QQ.sum\nexcept: pass',number=10^5)
100000 loops, best of 3: 741 ns per loop
# unpatched: 744 ns
sage: timeit('try: a.cartesian_product\nexcept: pass',number=10^5)
100000 loops, best of 3: 1.67 µs per loop
# unpatched: 3.89 µs

Best regards,
Simon

-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org

Reply via email to