The PY_TYPE_CHECK macro exists primarily because Cython didn't used to optimize isinstance.
On Mon, Dec 20, 2010 at 12:34 PM, Volker Braun <vbraun.n...@gmail.com> wrote: > 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. If A is a cdef'd type (which is the precondition for using PY_TYPE_CHECK), then "isinstance(x, A)" produces exactly the same code as "PY_TYPE_CHECK(x, A)" (a single inline call to PyObject_TypeCheck). Thus I'd say it's better to use the Pythonic isinstance. For some builtins it can use even more specialized code. > 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? No, it's because your loop is over 10000 rather than 1000. - Robert -- To post to this group, send email to sage-support@googlegroups.com To unsubscribe from this group, send email to sage-support+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sage-support URL: http://www.sagemath.org