Changes between Version 27 and Version 41 of Ticket #12808


Ignore:
Timestamp:
04/25/12 16:08:28 (10 years ago)
Author:
SimonKing
Comment:

I have attached my two patches. Your patch and my patch actually turn out to be independent.

Purpose of my first patch: Make NestedClassMetaclass an extension type of type, and avoid some calling overhead during its creation.

Purpose of my second patch: Make ClasscallMetclass an extension type as well, directly derived from NestedClassMetaclass.

Timings

With sage-5.1.notebook unpatched, I get for Florent's examples

sage: class Rien(object):
....:     pass
....:
sage: from sage.misc.classcall_metaclass import ClasscallMetaclass
sage: class NOCALL(object):
....:     __metaclass__ = ClasscallMetaclass
....:     pass
....:
sage: %timeit [Rien() for i in range(10000)]
125 loops, best of 3: 1.74 ms per loop
sage: %timeit [NOCALL() for i in range(10000)]
25 loops, best of 3: 16.7 ms per loop
sage: class CALL(object):
....:     __metaclass__ = ClasscallMetaclass
....:     @staticmethod
....:     def __classcall_private__(cls, arg):
....:         arg = arg + arg
....:         return arg
....:
sage: %timeit [CALL(i) for i in range(10000)]
25 loops, best of 3: 9.05 ms per loop

Here is something with __classcall__ instead of __classcall_private__, and in a way that has less overhead than arg+arg:

sage: class NewCall(object):
....:     __metaclass__ = ClasscallMetaclass
....:     @staticmethod
....:     def __classcall__(cls, C):
....:         return C
....:
sage: C = ZZ.__class__
sage: timeit("a = NewCall(C)", number=10000)
10000 loops, best of 3: 878 ns per loop

And finally a "nested class" example:

sage: from sage.misc.nested_class import NestedClassMetaclass
sage: def test_nest():
....:     class A:
....:         __metaclass__ = NestedClassMetaclass
....:         class B:
....:             pass
....:
sage: %timeit test_nest()
625 loops, best of 3: 33.1 µs per loop

Now, the same examples with my first patch:

sage: %timeit [Rien() for i in range(10000)]
125 loops, best of 3: 1.76 ms per loop
sage: %timeit [NOCALL() for i in range(10000)]
25 loops, best of 3: 18.3 ms per loop
sage: %timeit [CALL(i) for i in range(10000)]
25 loops, best of 3: 10.7 ms per loop
sage: %timeit test_nest()
625 loops, best of 3: 23.6 µs per loop

Now, with your patch only:

sage: %timeit [Rien() for i in range(10000)]
125 loops, best of 3: 1.77 ms per loop
sage: %timeit [NOCALL() for i in range(10000)]
125 loops, best of 3: 2.05 ms per loop
sage: %timeit [CALL(i) for i in range(10000)]
125 loops, best of 3: 4.34 ms per loop
sage: timeit("a = NewCall(C)", number=10000)
10000 loops, best of 3: 889 ns per loop
sage: %timeit test_nest()
625 loops, best of 3: 32.8 µs per loop

Thus, our patches treat orthogonal aspects. Now, the first two patches together:

sage: %timeit [Rien() for i in range(10000)]
125 loops, best of 3: 1.78 ms per loop
sage: %timeit [NOCALL() for i in range(10000)]
125 loops, best of 3: 2 ms per loop
sage: %timeit [CALL(i) for i in range(10000)]
125 loops, best of 3: 4.34 ms per loop
sage: timeit("a = NewCall(C)", number=10000)
10000 loops, best of 3: 895 ns per loop
sage: %timeit test_nest()
625 loops, best of 3: 23.6 µs per loop

And with all three patches:

sage: %timeit [Rien() for i in range(10000)]
125 loops, best of 3: 1.75 ms per loop
sage: %timeit [NOCALL() for i in range(10000)]
125 loops, best of 3: 2.08 ms per loop
sage: %timeit [CALL(i) for i in range(10000)]
125 loops, best of 3: 4.44 ms per loop
sage: timeit("a = NewCall(C)", number=10000)
10000 loops, best of 3: 897 ns per loop
sage: %timeit test_nest()
625 loops, best of 3: 23.6 µs per loop

CONCLUSION

My first patch does improve the time spent for the creation of a nested class. Your patch improves a lot of things for classcall metaclass. My second patch makes (I think) the inheritance a bit clearer, but it does not provide a speed-up. The reason is explained in my previous post.

Apply trac_12808-classcall_speedup-fh.patch trac_12808_nested_class_cython.patch trac_12808-classcall_cdef.patch

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #12808

    • Property Authors changed from Florent Hivert to Florent Hivert, Simon King
  • Ticket #12808 – Description

    v27 v41  
    33__Apply__
    44
    5 [attachment:trac_12808-classcall_speedup-fh.patch]
     5 * [attachment:trac_12808-classcall_speedup-fh.patch]
     6 * [attachment:trac_12808_nested_class_cython.patch]
     7
     8and we have to decide whether the third patch helps to make the code clearer:
     9
     10 * [attachment:trac_12808-classcall_cdef.patch]