私はcythonでいくつかのpythonコードをスピードアップしようとしています。私は、cythonの-a
オプションを使用して、どこで改善できるかを見ています。私の理解は、生成されたHTMLファイルでは、ハイライトされた行は、Python関数が呼び出される行です - それは正しいですか?Cython numpy配列インデックス
以下の簡単な関数では、バッファ構文を使用してnumpy配列の引数arr
を宣言しました。私はこれにより、インデックス作成操作をPython関数を呼び出すことなくCで行うことができると考えました。しかし、cython -a
(バージョン0.15)は、要素の値を設定する行を強調表示していますが、要素の1つを読み取った部分ではありませんが、arr
の値が設定されています。なぜこれが起こるのですか? numpyの配列要素にアクセスするより効率的な方法はありますか?
import numpy
cimport numpy
def foo(numpy.ndarray[double, ndim=1] arr not None):
cdef int i
cdef double elem
for i in xrange(10):
elem = arr[i] #not highlighted
arr[i] = 1.0 + elem #highlighted
EDIT:また、どのようにmode
バッファ引数はnumpyのと対話していますか? order
引数がnumpy.array
に変更されていないと仮定すると、いつもmode='c'
を使用しても安全ですか?これは実際にパフォーマンスに影響を及ぼしますか?
delnanのコメント後に編集:arr[i] += 1
も強調表示されています(そのため、最初に分割して問題の原因となっている部分を確認しています)。私は(これは強調表示する内容に違いはありません)物事を単純化するために境界チェックをオフにした場合、生成されたCコードは次のとおりです。
/* "ct.pyx":11
* cdef int i
* cdef double elem
* for i in xrange(10): # <<<<<<<<<<<<<<
* elem = arr[i]
* arr[i] = 1.0 + elem
*/
for (__pyx_t_1 = 0; __pyx_t_1 < 10; __pyx_t_1+=1) {
__pyx_v_i = __pyx_t_1;
/* "ct.pyx":12
* cdef double elem
* for i in xrange(10):
* elem = arr[i] # <<<<<<<<<<<<<<
* arr[i] = 1.0 + elem
*/
__pyx_t_2 = __pyx_v_i;
__pyx_v_elem = (*__Pyx_BufPtrStrided1d(double *, __pyx_bstruct_arr.buf, __pyx_t_2, __pyx_bstride_0_arr));
/* "ct.pyx":13
* for i in xrange(10):
* elem = arr[i]
* arr[i] = 1.0 + elem # <<<<<<<<<<<<<<
*/
__pyx_t_3 = __pyx_v_i;
*__Pyx_BufPtrStrided1d(double *, __pyx_bstruct_arr.buf, __pyx_t_3, __pyx_bstride_0_arr) = (1.0 + __pyx_v_elem);
}
は '[i]が+ = 1 '強調しARRですか?また、 'cython -a'によって生成されたHTML文書の中で、その特定の行のために生成されたコードを見ることができます。おそらく、Python API呼び出しがその行でどのように起こるかを知るのに役立ちます。 – delnan