2012-12-17 9 views
5

ich folgende Inline-Funktion für Cython habenCython: Inline-Funktion nicht rein C

cpdef inline int c_rate2recs_2(int maxNN,int idx): 
    cdef int out=idx%maxNN 
    return out 

jedoch diese in

/* 
* return out 
* 
* cpdef inline int c_rate2recs_2(int maxNN,int idx):    # <<<<<<<<<<<<<< 
* cdef int out=idx%maxNN 
* return out 
*/ 

static PyObject *__pyx_pw_6kmc_cy_5c_rate2recs_2(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ 
static CYTHON_INLINE int __pyx_f_6kmc_cy_c_rate2recs_2(int __pyx_v_maxNN, int __pyx_v_idx, CYTHON_UNUSED int __pyx_skip_dispatch) { 
    int __pyx_v_out; 
    int __pyx_r; 
    __Pyx_TraceDeclarations 
    __Pyx_RefNannyDeclarations 
    __Pyx_RefNannySetupContext("c_rate2recs_2", 0); 
    __Pyx_TraceCall("c_rate2recs_2", __pyx_f[0], 984); 

/* 
* return out 
* 
* cpdef inline int c_rate2recs_2(int maxNN,int idx):    # <<<<<<<<<<<<<< 
* cdef int out=idx%maxNN 
* return out 
*/ 

static PyObject *__pyx_pf_6kmc_cy_4c_rate2recs_2(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_maxNN, int __pyx_v_idx) { 
    PyObject *__pyx_r = NULL; 
    __Pyx_TraceDeclarations 
    __Pyx_RefNannyDeclarations 
    __Pyx_RefNannySetupContext("c_rate2recs_2", 0); 
    __Pyx_TraceCall("c_rate2recs_2", __pyx_f[0], 984); 
    __Pyx_XDECREF(__pyx_r); 
    __pyx_t_1 = PyInt_FromLong(__pyx_f_6kmc_cy_c_rate2recs_2(__pyx_v_maxNN, __pyx_v_idx, 0)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 
    __Pyx_GOTREF(__pyx_t_1); 
    __pyx_r = __pyx_t_1; 
    __pyx_t_1 = 0; 
    goto __pyx_L0; 

    __pyx_r = Py_None; __Pyx_INCREF(Py_None); 
    goto __pyx_L0; 
    __pyx_L1_error:; 
    __Pyx_XDECREF(__pyx_t_1); 
    __Pyx_AddTraceback("kmc_cy.c_rate2recs_2", __pyx_clineno, __pyx_lineno, __pyx_filename); 
    __pyx_r = NULL; 
    __pyx_L0:; 
    __Pyx_XGIVEREF(__pyx_r); 
    __Pyx_TraceReturn(__pyx_r); 
    __Pyx_RefNannyFinishContext(); 
    return __pyx_r; 
} 

übersetzt Wie ich in der cython Geschäft ziemlich neu bin, würde Ich mag an wissen, wie man die meisten Python-Befehle loswird (cython -a kennzeichnet diese Inline als ziemlich weit entfernt von reinem C).

+2

Haben Sie es mit 'cdef' anstelle von' cpdef' versucht? Ich dachte, dass mit 'cpdef 'nur reines C für C-Funktionen sein wird. – tiago

+0

Danke, das hat mein Problem gelöst. Allerdings war die Leistungssteigerung in diesem Fall vernachlässigbar – bios

+0

für eine so kleine Funktion ist es besser, keine Funktion zu haben. Funktionsaufrufe fügen Overhead hinzu. – tiago

Antwort

3

Wie ich in dem cython Geschäft ziemlich neu bin, würde ich gerne wissen, wie die meisten der Python-Befehle, um loszuwerden (cython -a flags diese Inline als ziemlich weit weg von den reinen C)

Der Trick ist, dass wenn Sie Ihre Funktion nogil aufrufen können;

dann was auch immer gelb Sie sehen, geht eigentlich nicht wirklich zu Python. Es könnte zum Beispiel ein Fehlerfall sein, oder es könnte einfach eine andere Art von milder Prüfung sein. Im Fall von cpdef wird nicht nur eine pure-C-Funktion erstellt, sondern auch ein Python-Alias ​​zum Aufruf aus einem Python-Bereich erstellt. Dies wirkt sich nicht auf die Geschwindigkeit aus.

In diesem Fall zeigten einige Zeiten gegen eine manuell inlined Schleife keine Verlangsamungen, und das Entfernen von inline tat auch nichts zur Zeit. Ich stelle mir vor, dass ein Fall, der schwieriger zu optimieren ist, verschiedene Eigenschaften aufweisen kann, aber der Schlüssel ist Profil.

Schließlich können Beschleunigungen und Beseitigung von einigen der Fehlerprüfung mit compiler directives durchgeführt werden.