Repeated method lookup via the vtab can be redundant. Consider the following code
cdef class Root: cdef long i def __cinit__(self): self.i = 0 cdef void inc(self): self.i += 1 cdef class A(Root): def inc_many(self, long N): cdef long i = 0 for i from 0 <= i < N: self.inc()
A().inc_many(10**9) takes 3.51 seconds on my machine. Assigning the self.vtab to a local pointer, and using that for all the calls to inc cuts down the runtime to 3.39 seconds, and assigning the vtab to a local struct (rather than just a pointer, though this has higher overhead) cuts it down to 3.04 seconds. Given that types of objects are immutable, this might be worth doing in some cases.