PY_TYPE_CHECK is just a wrapper macro around PyObject_TypeCheck which
dereferences and compares the object type fields. So that part should be
insanely fast.
sage: cython('cpdef t(x):\n for i in range(0,1000):\n
PY_TYPE_CHECK(x,int)'); timeit("t(5000)", repeat=100)
625 loops, best of 100: 14.1 µs per loop
sage: cython('cpdef t(x):\n for i in range(0,1000):\n
PY_TYPE_CHECK(x,float)'); timeit("t(5000)", repeat=100)
625 loops, best of 100: 14.1 µs per loop
sage: cython('cpdef t(x):\n for i in range(0,1000):\n
isinstance(x,int)'); timeit("t(5000)", repeat=100)
625 loops, best of 100: 182 ns per loop
sage: cython('cpdef t(x):\n for i in range(0,1000):\n
isinstance(x,float)'); timeit("t(5000)", repeat=100)
625 loops, best of 100: 14.1 µs per loop
It seems like isinstance and PY_TYPE_CHECK are equally fast, except that
isinstance caches the result if it was positive.
But if you really write Cython code then you probably want to type the
argument so that the compiler knows what x is. Then I get
sage: cython('cpdef t(int x):\n for i in range(0,1000):\n
PY_TYPE_CHECK(x,int)'); timeit("t(5000)", repeat=100)
625 loops, best of 100: 7.72 µs per loop
sage: cython('cpdef t(int x):\n for i in range(0,1000):\n
PY_TYPE_CHECK(x,float)'); timeit("t(5000)", repeat=100)
625 loops, best of 100: 12 µs per loop
sage: cython('cpdef t(int x):\n for i in range(0,10000):\n
isinstance(x,int)'); timeit("t(5000)", repeat=100)
625 loops, best of 100: 111 µs per loop
sage: cython('cpdef t(int x):\n for i in range(0,10000):\n
isinstance(x,float)'); timeit("t(5000)", repeat=100)
625 loops, best of 100: 118 µs per loop
Now isinstance is a lot slower, while PY_TYPE_CHECK got moderately faster. I
guess isinstance calls from C into Python while the PY_TYPE_CHECK stays in
C?
--
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/sage-support
URL: http://www.sagemath.org