Good news! The change for including the Py_TPFLAGS_HAVE_VERSION_TAG
for cython types by default is trivial and will likely make it into
cython 0.19. See:

https://groups.google.com/group/cython-users/browse_thread/thread/5110f344ea2e6e86?hl=en

To see what kind of effect we can expect in sage I checked 5.19b4,
both vanilla and with the flag added
(the easiest way is probably to include the flag in local/lib/python/
site-packages/Cython/Compiler/TypeSlots.py, line 380 and then doing
'sage -ba' to rebuild the library) and it's quite noticable:

make ptest: Vanilla 5.9beta4

Total time for all tests: 1423.2 seconds
    cpu time: 1870.8 seconds
    cumulative wall time: 5026.0 seconds

make ptest: 5.9beta4 with cython attribute caching

Total time for all tests: 1308.8 seconds
    cpu time: 1794.7 seconds
    cumulative wall time: 4825.2 seconds

Timing of make ptest can be tricky, so picking for instance devel/sage/
sage/combinat/sf/k_dual.py, which seems to quite heavily use python
classes:

vanilla:

sage -t devel/sage/sage/combinat/sf/k_dual.py
    [247 tests, 7.56 s]
----------------------------------------------------------------------
All tests passed!
----------------------------------------------------------------------
Total time for all tests: 7.6 seconds
    cpu time: 7.2 seconds
    cumulative wall time: 7.6 seconds

attribute caching:

sage -t devel/sage/sage/combinat/sf/k_dual.py
    [247 tests, 6.71 s]
----------------------------------------------------------------------
All tests passed!
----------------------------------------------------------------------
Total time for all tests: 6.8 seconds
    cpu time: 6.3 seconds
    cumulative wall time: 6.7 seconds

To illustrate, consider

class P(sage.structure.parent.Parent):
     @cached_method
     def P(self):
         return 1

On vanilla, we get

sage: p=P()
sage: p.t=1
sage: p.P()
1
sage: p.t
1
sage: timeit('p.P()',number=200000,repeat=100)
200000 loops, best of 100: 91.8 ns per loop
sage: timeit('p.t',number=200000,repeat=100)
200000 loops, best of 100: 98.9 ns per loop

i.e., cached_method is a little faster, because the method P is found
earlier in the MRO (instance attributes can be shadowed by data
escriptors anywhere in the MRO, so the whole MRO needs to be walked
for instance attributes; the worst case)

With attribute caching this problem goes away, so everything is
faster:

sage: timeit('p.P()',number=200000,repeat=100)
200000 loops, best of 100: 80 ns per loop
sage: timeit('p.t',number=200000,repeat=100)
200000 loops, best of 100: 50.3 ns per loop

but since the absence of a class attribute t in the MRO gets cached as
well, the lookup of the instance attribute is now by far the fastest.
It's just a dict lookup, no computation or calling necessary (which
still causes a little overhead for the cached method).

We should upgrade to Cython 0.19 as soon as it's out. Or if someone
feels like it, we can already patch the cython in sage.

-- 
You received this message because you are subscribed to the Google Groups 
"sage-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-devel+unsubscr...@googlegroups.com.
To post to this group, send email to sage-devel@googlegroups.com.
Visit this group at http://groups.google.com/group/sage-devel?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to