I'm currently reading about the @cython.final
decorator, and I'm wondering whether it adds any performance benefits at runtime or only prevents certain actions throwing errors as documented in
https://cython.readthedocs.io/en/latest/src/userguide/extension_types.html
Thanks,
I'm wondering whether it adds any performance benefits at runtime
Yes.
The main advantage is when calling cdef/cpdef
functions. Consider:
cdef class C:
cdef f(self):
...
def some_func(C c):
c.f()
without final
this would call either C.f
or an overridden function in any derived class. This call looks like:
((struct __pyx_vtabstruct_3fnl_C *)__pyx_v_c->__pyx_vtab)->f(__pyx_v_c);
(i.e. it goes through a "vtable" and two pointer-dereferences to work out the actual function called.)
With final
the call looks like
__pyx_f_3fnl_1C_f(__pyx_v_c)
(i.e. it knows the exact function at compile-time and goes through no pointer-dereferences).
With cpdef
the difference is even more dramatic because cpdef
functions may be overridden by derived classes implemented in Python, so the check involves a dict
lookup too.
There's also some other optimizations:
__dict__
for each instance.The optimization of method calls is the main one (and is fairly general and will apply to most languages with have the concept of a "final" type).