Ich habe ein Problem mit meinem Code cythonizing, insbesondere die folgende (und ähnlichen) sniplets:Wie vermeidet man PyObject_to_MemoryviewSlice, GOTREF/DECREF Python API Aufrufe?
cdef double [:,:] grad_d_him_d_jm
grad_d_ihm_d_jm = grad_d_im_d_jm(...)
wo grad_d_im_d_jm (...) einen doppelten zurückkehren würde [:,:] memoryview. Dieser Code würde durch Cython in den folgenden C-Code übersetzt werden:
__pyx_t_1 = __pyx_f_24gradient_better_c_mviews_grad_d_im_d_jm(__pyx_v_i, __pyx_v_j, __pyx_v_m, __pyx_v_structure, __pyx_v_distances);
if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
__pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(__pyx_t_1);
if (unlikely(!__pyx_t_7.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_v_grad_d_ihm_d_jm = __pyx_t_7;
__pyx_t_7.memview = NULL;
__pyx_t_7.data = NULL;
Während ich dies in Schleifen mache, ich vermute, dass die Python-API ganz gewissen Einfluss auf die Geschwindigkeit meines Code haben, nennt.
die GOTREF/DECREF Anruf tritt auch bei anderen Gelegenheiten, zusammen mit einem PyFloat_asFloat:
cdef float sp
sp = scalar_product()
wo scalar_product() eine cdef Schwimmers zurückgibt. Dieser Ausschnitt wird auf
übersetzt__pyx_t_1 = __pyx_f_24gradient_better_c_mviews_scalar_product(__pyx_v_i, __pyx_v_j, __pyx_v_m, __pyx_v_structure);
if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
__pyx_t_2 = __pyx_PyFloat_AsFloat(__pyx_t_1);
if (unlikely((__pyx_t_2 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_v_sp = __pyx_t_2;
ich Python bin mit 2.7.11+ und Cython 0.23.4. Ich wäre Ihnen sehr dankbar, wenn Sie mir entweder mitteilen könnten, dass dies für die Leistung nicht relevant ist oder b) wie Sie es beheben können. Lassen Sie mich wissen, wenn ich die Frage verbessern kann, würde ich mich freuen, dies zu tun.
Dank weg geben für Ihre Antworten! scalar_product ist ein cdef und sein zurückgegebener Wert ist ein cdef-float. Das gleiche gilt für grad_d_im_d_jm; nur, dass der zurückgegebene Wert eine 2D-Speicheransicht mit Float-Typ ist. Beim Drucken (grad_d_im_d_jm) heißt es, dass es sich um eine Memory-Ansicht handelt. Was ich in grad_d_im_d_jm() mache, initialisiert einen memoryview mit mv = numpy.zeros ((n, n)) und fügt dann Sachen zu einzelnen Elementen hinzu. Ich habe mir das Refnanny-Ding angeschaut, konnte aber noch keinen Weg finden es abzuschalten (nur als Option für runtests.py). Würdest du zufällig einen kennen? –
Nanny wird nur verwendet, um Cython selbst zu debuggen. Z.B. Die generierte C-Datei hat ein ifdef, das "__Pyx_DECREF" durch "Py_DECREF" ersetzt, sofern der Benutzer nicht ausdrücklich "-DYTHON_REFNANY" festgelegt hat. –
Ist es möglich, den relevanten Code zu teilen? Ich kann das Problem nicht lokal mit Stub-Funktionen reproduzieren. –