2016-06-30 17 views
4

私はPythonでかなり大きなシミュレーションを書いており、Cythonからいくつかの追加のパフォーマンスを得ることを望んでいました。しかし、以下のコードでは、かなり大きなループが含まれていても、それほど多くを得ていないようです。およそ100,000回の反復。Cythonの最適化

私は初心者の間違いを作ったのですか、このループの大きさは大きかったのですか? (私のテストでは、Cythonコードは約2倍の速さでした)。

import numpy as np; 
cimport numpy as np; 
import math 

ctypedef np.complex64_t cpl_t 
cpl = np.complex64 

def example(double a, np.ndarray[cpl_t,ndim=2] A): 

    cdef int N = 100 

    cdef np.ndarray[cpl_t,ndim=3] B = np.zeros((3,N,N),dtype = cpl) 

    cdef Py_ssize_t n, m; 
    for n in range(N): 
     for m in range(N): 

      if np.sqrt(A[0,n]) > 1: 
       B[0,n,m] = A[0,n] + 1j * A[0,m] 

    return B; 
+6

あなたはループの中で 'np.sqrt'呼び出しを行っています。パフォーマンスの問題のように見えます。とにかくそれはなぜループに入っていますか? 'a'は決して変化しません。なぜ、a <= 1ならば、ループの前にBを返しますか? – user2357112

+0

@GWW:それは私の最初の行のように見えます。 – user2357112

+0

@ user2357112これは実際に私が見落としたものですが、私はそれを外に出すことができます。実際には、np.sqrt()やnp.exp()のような数学演算は、私がcythonで避けなければならないものですか? – physicsGuy

答えて

7

コンパイラ指令を使用する必要があります。私は

import numpy as np 

def example_python(a, A): 
    N = 100 
    B = np.zeros((3,N,N),dtype = np.complex) 
    aux = np.sqrt(A[0]) 
    for n in range(N): 
     if aux[n] > 1: 
      for m in range(N): 
       B[0,n,m] = A[0,n] + 1j * A[0,m] 
return B 

とCythonに

import cython 
import numpy as np 
cimport numpy as np 

ctypedef np.complex64_t cpl_t 
cpl = np.complex64 

@cython.boundscheck(False) # compiler directive 
@cython.wraparound(False) # compiler directive 
def example_cython(double a, np.ndarray[cpl_t,ndim=2] A): 

    cdef int N = 100 
    cdef np.ndarray[cpl_t,ndim=3] B = np.zeros((3,N,N),dtype = cpl) 
    cdef np.ndarray[float, ndim=1] aux 
    cdef Py_ssize_t n, m 
    aux = np.sqrt(A[0,:]).real 
    for n in range(N): 
     if aux[n] > 1.: 
      for m in range(N): 
       B[0,n,m] = A[0,n] + 1j * A[0,m] 
    return B 

は、私は〜450倍速くより

c = np.array(np.random.rand(100,100)+1.5+1j*np.random.rand(100,100), dtype=np.complex64) 

%timeit example_python(100, c) 
10 loops, best of 3: 61.8 ms per loop 

%timeit example_cython(100, c) 
10000 loops, best of 3: 134 µs per loop 

Cythonは両方の機能を比較(あなたはコンパイラディレクティブhereについて学ぶことができます)Pythonの

であなたの関数を書きましたこの場合はPythonです。

+0

ありがとう、それはまさに私が探していたものでした!私はまだコンパイラ指令について知らなかった。 – physicsGuy