1
的大小當我嘗試編譯下面的代碼,我得到的錯誤用Cython讓吉爾走的時候,我需要numpy的陣列
return sign_match.sum()/y_true.shape[0] ^
轉換爲Python對象不得擅自吉爾
有沒有簡單的方法來克服這一點?我能想到的最可行的解決方案是將數組的長度作爲另一個參數傳遞。我正在使用python 3.3.5。
的大小當我嘗試編譯下面的代碼,我得到的錯誤用Cython讓吉爾走的時候,我需要numpy的陣列
return sign_match.sum()/y_true.shape[0] ^
轉換爲Python對象不得擅自吉爾
有沒有簡單的方法來克服這一點?我能想到的最可行的解決方案是將數組的長度作爲另一個參數傳遞。我正在使用python 3.3.5。
y_true
和y_pred
是數組,因而Python對象。因此,任何使用它們的操作都需要gil
,而不僅僅是形狀。
嘗試編譯沒有nogil
,並看看-a
html。哪些行是深黃色的,有很多Python對象引用?
+11: return -(err * err).sum()/y_true.shape[0]
__pyx_t_7 = PyNumber_Multiply(((PyObject *)__pyx_v_err), ((PyObject *)__pyx_v_err)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 11, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_7);
__pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_sum); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 11, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_8);
__Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
....
只是您的文件的擴展C代碼的一部分。查看所有Pyx..
調用。他們都需要gil
。
http://docs.cython.org/en/latest/src/userguide/memoryviews.html表明您可以在numpy數組的內存視圖上使用nogil
。
從memoryview指南繪製我寫了這個替代功能
cpdef double neg_mse_view(double[:] y_true, double[:] y_pred):
cdef double x, res
cdef int I
I = y_true.shape[0]
res = 0
for i in range(I):
x = y_true[i]-y_pred[i]
res += -(x*x)
res = res/I
return res
這可以用同樣的方法被調用。這些時間表現出2x加速。 nogil
工程,但沒有區別。
In [10]: a=np.arange(1000000.)
In [11]: timeit negmse.negative_mse(a,a-10)
10 loops, best of 3: 16.9 ms per loop
In [12]: timeit negmse.neg_mse_view(a,a-10)
100 loops, best of 3: 7.17 ms per loop
In [13]: timeit negmse.neg_mse_nogil(a,a-10)
100 loops, best of 3: 7.19 ms per loop
對於函數這個簡單的,純粹的numpy的版本基本上是一樣好:
In [20]: timeit ((a-(a-10))**2).sum()/a.shape[0]
100 loops, best of 3: 16.8 ms per loop
TY TY!哈哈我會認爲numpy會一樣快。我想在循環中使用nogil函數(一個更大的進程的一小部分)。我只是想要一個簡單的例子來開始。這非常有幫助。 – itzjustricky