Opened 8 years ago

Closed 8 years ago

#14100 closed enhancement (fixed)

Make raising attribute errors faster

Reported by: SimonKing Owned by: tbd
Priority: major Milestone: sage-5.8
Component: performance Keywords: AttributeError
Cc: Merged in: sage-5.8.beta2
Authors: Simon King Reviewers: Volker Braun
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: Stopgaps:

Status badges

Description

At #11342, getattr on parents and elements became faster, among other tricks, by supplying a "lazy" error message sage.structure.misc.AttributeErrorMessage. Namely, creating the error message as a string, even as a lazy string, took too much time.

Here, I suggest to go one step further: sage.structure.misc, sage.structure.element and sage.structure.parent should store a fixed instance of AttributeError whose error message is a fixed instance of AttributeErrorMessage. When raising an attribute error, one can then just change the previously created error message in-place and then raise the previously created AttributeError.

Hence, the time for creating the attribute error is saved.

Attachments (1)

trac_14100-dummy_attribute_error.patch (7.8 KB) - added by SimonKing 8 years ago.

Download all attachments as: .zip

Change History (4)

Changed 8 years ago by SimonKing

comment:1 Changed 8 years ago by SimonKing

  • Authors changed from SimonKing to Simon King
  • Status changed from new to needs_review

Here are some timings, similar to what we did on #11342.

sage-5.6.rc0 with patch:

sage: a = 1
sage: timeit('try: QQ.__bla\nexcept: pass')
625 loops, best of 3: 3.85 µs per loop
sage: timeit('try: a.__bla\nexcept: pass')
625 loops, best of 3: 2.47 µs per loop
sage: timeit('try: QQ.__bla_\nexcept: pass')
625 loops, best of 3: 5.71 µs per loop
sage: timeit('try: QQ.__bla_\nexcept: pass')
625 loops, best of 3: 5.78 µs per loop
sage: timeit('try: a.__bla_\nexcept: pass')
625 loops, best of 3: 5.35 µs per loop
sage: timeit('try: QQ.bla\nexcept: pass')
625 loops, best of 3: 5.78 µs per loop
sage: timeit('try: a.bla\nexcept: pass')
625 loops, best of 3: 4.92 µs per loop
sage: timeit('try: QQ.sum\nexcept: pass',number=10^5)
100000 loops, best of 3: 1.13 µs per loop
sage: timeit('try: a.cartesian_product\nexcept: pass',number=10^5)
100000 loops, best of 3: 2.1 µs per loop

Without the patch:

sage: a = 1
sage: timeit('try: QQ.__bla\nexcept: pass')
625 loops, best of 3: 4.31 µs per loop
sage: timeit('try: a.__bla\nexcept: pass')
625 loops, best of 3: 3 µs per loop
sage: timeit('try: QQ.__bla_\nexcept: pass')
625 loops, best of 3: 6.11 µs per loop
sage: timeit('try: a.__bla_\nexcept: pass')
625 loops, best of 3: 5.49 µs per loop
sage: timeit('try: QQ.bla\nexcept: pass')
625 loops, best of 3: 6.06 µs per loop
sage: timeit('try: a.bla\nexcept: pass')
625 loops, best of 3: 5.4 µs per loop
sage: timeit('try: QQ.sum\nexcept: pass',number=10^5)
100000 loops, best of 3: 1.12 µs per loop
sage: timeit('try: a.cartesian_product\nexcept: pass',number=10^5)
100000 loops, best of 3: 2.35 µs per loop

I think the speed-up is significant.

Last edited 8 years ago by SimonKing (previous) (diff)

comment:2 Changed 8 years ago by vbraun

  • Reviewers set to Volker Braun
  • Status changed from needs_review to positive_review

Looks good to me...

comment:3 Changed 8 years ago by jdemeyer

  • Merged in set to sage-5.8.beta2
  • Resolution set to fixed
  • Status changed from positive_review to closed
Note: See TracTickets for help on using tickets.