コード、より具体的には次の(および同様の)スニペットのサイトン化に問題があります。
cdef double [:,:] grad_d_him_d_jm
grad_d_ihm_d_jm = grad_d_im_d_jm(...)
grad_d_im_d_jm(...) は double [:,:] メモリビューを返します。このコードは、Cython によって次の C コードに変換されます。
__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;
これをループで行っているため、Python API 呼び出しがコードの速度にかなりの影響を与えていると思われます。
GOTREF / DECREF 呼び出しは、PyFloat_asFloat とともに、他の機会にも発生します。
cdef float sp
sp = scalar_product()
scalar_product() は cdef float を返します。このスニペットは翻訳されます
__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;
Python 2.7.11+ と Cython 0.23.4 を実行しています。a) これはパフォーマンスには関係ないか、b) 修正方法のいずれかを教えていただければ幸いです。質問を改善できるかどうか教えてください。喜んでそうします。