[Pyrex] [Cython-dev] where is Cython 'cpdef'
Robert Bradshaw
robertwb at math.washington.edu
Wed Oct 31 17:22:05 CET 2007
On Oct 31, 2007, at 12:57 AM, David McNab wrote:
> On Tue, 2007-10-30 at 23:31 -0700, Robert Bradshaw wrote:
>>> Can you please point me to the version/branch of cython that has
>>> cpdef
>>> support?
>
>> I'm going to be releasing that branch later tonight/tomorrow, it
>> looks like in the current repository it's still called rdef.
>
> Hi,
>
> Will the new 'cpdef' keyword do the same as the current 'rdef'?
Yes.
> I tried out 'rdef' from the current repo, and it is indeed creating a
> 'C' and a 'Python' verion of the same method. But I notice that the
> generated C method seems to carry a lot of Python baggage.
True, but it is a fixed amount of baggage on (in your case) a tiny
function. More importantly, the whole block is surrounded by
if (unlikely(((PyObject *)__pyx_v_self)->ob_type->tp_dictoffset != 0)) {
...
}
so it won't get executed for cdef classes (and this test is very fast).
- Robert
>
> Consider:
>
> rdef int area(self):
> return self.width * self.height
>
> This generates:
>
> ----------------------------------
> /*
> * not-so-thin C method
> */
>
> static PyObject *__pyx_f_py_6myshit_4Rect_area(PyObject *__pyx_v_self,
> PyObject *unused); /*proto*/
> static int __pyx_f_6myshit_4Rect_area(struct __pyx_obj_6myshit_Rect
> *__pyx_v_self) {
> int __pyx_r;
> PyObject *__pyx_1 = 0;
> PyObject *__pyx_2 = 0;
> int __pyx_3;
> Py_INCREF(__pyx_v_self);
> if (unlikely(((PyObject *)__pyx_v_self)->ob_type->tp_dictoffset !
> = 0))
> {
> __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self),
> __pyx_n_area); if (unlikely(!((PyObject *)__pyx_v_self)))
> {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; goto __pyx_L1;}
> if (!(strcmp(__pyx_1->ob_type->tp_name,
> "builtin_function_or_method") == 0) ||
> (PyCFunction_GET_FUNCTION(__pyx_1) !=
> &__pyx_f_py_6myshit_4Rect_area)) {
> __pyx_2 = PyObject_CallObject(__pyx_1, 0); if (unlikely(!
> __pyx_2))
> {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; goto __pyx_L1;}
> Py_DECREF(__pyx_1); __pyx_1 = 0;
> __pyx_3 = PyInt_AsLong(__pyx_2); if (unlikely((__pyx_3 == -1) &&
> PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11;
> goto
> __pyx_L1;}
> Py_DECREF(__pyx_2); __pyx_2 = 0;
> __pyx_r = __pyx_3;
> goto __pyx_L0;
> }
> }
> __pyx_r = (__pyx_v_self->width * __pyx_v_self->height);
> goto __pyx_L0;
>
> __pyx_r = 0;
> goto __pyx_L0;
> __pyx_L1:;
> Py_XDECREF(__pyx_1);
> Py_XDECREF(__pyx_2);
> __Pyx_WriteUnraisable("myshit.Rect.area");
> __pyx_L0:;
> Py_DECREF(__pyx_v_self);
> return __pyx_r;
> }
>
> /*
> * thin-ish Python wrapper method
> */
>
> static PyObject *__pyx_f_py_6myshit_4Rect_area(PyObject *__pyx_v_self,
> PyObject *unused); /*proto*/
> static PyObject *__pyx_f_py_6myshit_4Rect_area(PyObject *__pyx_v_self,
> PyObject *unused) {
> PyObject *__pyx_r;
> PyObject *__pyx_1 = 0;
> Py_INCREF(__pyx_v_self);
> __pyx_1 = PyInt_FromLong(((struct __pyx_vtabstruct_6myshit_Rect
> *)((struct __pyx_obj_6myshit_Rect
> *)__pyx_v_self)->__pyx_vtab)->area(((struct __pyx_obj_6myshit_Rect
> *)__pyx_v_self))); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f
> [0];
> __pyx_lineno = 11; goto __pyx_L1;}
> __pyx_r = __pyx_1;
> __pyx_1 = 0;
> goto __pyx_L0;
>
> __pyx_r = Py_None; Py_INCREF(Py_None);
> goto __pyx_L0;
> __pyx_L1:;
> Py_XDECREF(__pyx_1);
> __Pyx_AddTraceback("myshit.Rect.area");
> __pyx_r = 0;
> __pyx_L0:;
> Py_DECREF(__pyx_v_self);
> return __pyx_r;
> }
> ------------------------
>
> Compare this to the other approach, of defining 2 methods:
>
> cdef int _area(self):
> return self.width * self.height
>
> def area(self):
> return self._area()
>
> which generates:
>
> --------------------------------------
> /* thin C version */
>
> static int __pyx_f_6myshit_4Rect__area(struct __pyx_obj_6myshit_Rect
> *__pyx_v_self) {
> int __pyx_r;
> Py_INCREF(__pyx_v_self);
> __pyx_r = (__pyx_v_self->width * __pyx_v_self->height);
> goto __pyx_L0;
> __pyx_r = 0;
> __pyx_L0:;
> Py_DECREF(__pyx_v_self);
> return __pyx_r;
> }
>
> /* Python wrapper method */
>
> static PyObject *__pyx_f_py_6myshit_4Rect_area(PyObject *__pyx_v_self,
> PyObject *unused); /*proto*/
> static PyObject *__pyx_f_py_6myshit_4Rect_area(PyObject *__pyx_v_self,
> PyObject *unused) {
> PyObject *__pyx_r;
> PyObject *__pyx_1 = 0;
> Py_INCREF(__pyx_v_self);
> __pyx_1 = PyInt_FromLong(((struct __pyx_vtabstruct_6myshit_Rect
> *)((struct __pyx_obj_6myshit_Rect
> *)__pyx_v_self)->__pyx_vtab)->_area(((struct __pyx_obj_6myshit_Rect
> *)__pyx_v_self))); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f
> [0];
> __pyx_lineno = 18; goto __pyx_L1;}
> __pyx_r = __pyx_1;
> __pyx_1 = 0;
> goto __pyx_L0;
> __pyx_r = Py_None; Py_INCREF(Py_None);
> goto __pyx_L0;
> __pyx_L1:;
> Py_XDECREF(__pyx_1);
> __Pyx_AddTraceback("myshit.Rect.area");
> __pyx_r = 0;
> __pyx_L0:;
> Py_DECREF(__pyx_v_self);
> return __pyx_r;
> }
> ------------------------------------
>
> Any words of wisdom on this?
>
> Cheers
> David
>
>
>
> _______________________________________________
> Cython-dev mailing list
> Cython-dev at lists.berlios.de
> https://lists.berlios.de/mailman/listinfo/cython-dev
More information about the Pyrex
mailing list