2017-08-28 7 views
0

スピードを上げているためにはサイレントコードに変更するだけですより多くの速度を得るためにGILを削除してマルチスレッドを行うことができます。私のループのための二重の部分で、私は最終的に成功し、いくつかのpythonでcython VS率10純粋なCを獲得し、再び(PRANGEで)4つのスレッドを使用して、因子3仲間stackoverflowのユーザーの助けを借りてCythonはnumpy ndarray(N、4,2)をベクターに変換します。

コード。私が最初にvector[vector[pair[double,double]]]寸法(N、4,2)(及び(K、4,2))の2個の3次元numpy ndarraysを変換する必要があり、このループに入るために

BUT。 KとNはかなり大きい。このため

私がやっている:

cdef int N=200000 #Of this order of magnitude 
cdef np.ndarray[DTYPE_t,ndim=3] numpy_array=np.random.uniform(size=(N,4,2)) 
t1=time.time() 
cdef vector[vector[pair[double,double]]] c_structure 
c_structure.reserve(N) 
cdef int i 
for i in range(N): 
    c_structure.push_back(numpy_array[i]) 
t2=time.time() 

しかし、私は些細なが私のコードの新しいボトルネックとなっているとみなされるコードのこの部分を!!! double forループは、私のコンピュータにかかります0.1s(元の実装では1.11sではなく)シングルスレッドで、この部分は3秒間で続きます(各配列1.5s)!これは私の超最適化されたコードを元のコード(1.5 * 2 + 0.1)よりも3倍遅くする!

私は間違っていますか?これをスピードアップする方法は?

はあなたがNx4x2配列を持っていて、vector[vector[pair[double,double]]に変換されanother related question that I asked

+1

本当に重要ではないが、 'np.random.uniform((N、4,2))' 3次元配列を返しません... [mcve]を少なくとも比較的正確にするようにしてください。 – MSeifert

+0

ありがとうございました – jean

+0

ほとんどの場合、乱数を生成することは可能でしょうか? –

答えて

0

ベクトルの各要素を明示的に初期化することで、100倍の速度を得ました。確かにcythonで - 今は0の黄色の線があります。

cdef int N=200000 #Of this order of magnitude 
cdef np.ndarray[DTYPE_t,ndim=3] numpy_array=np.random.uniform(size=(N,4,2)) 
t1=time.time() 
cdef vector[vector[pair[double,double]]] c_structure 
cdef vector[pair[double,double]] empty_vector, vector 
cdef pair[double,double] a1, a2, a3, a4 
c_structure.reserve(N) 
cdef int i 
for i in range(N): 
    a1.first=numpy_array[i,0,0] 
    a1.second=numpy_array[i,0,1] 
    a2.first=numpy_array[i,1,0] 
    a2.second=numpy_array[i,1,1] 
    a3.first=numpy_array[i,2,0] 
    a3.second=numpy_array[i,2,1] 
    a4.first=numpy_array[i,3,0] 
    a4.second=numpy_array[i,3,1] 
    vector.push_back(a1) 
    vector.push_back(a2) 
    vector.push_back(a3) 
    vector.push_back(a4) 
    c_structure.push_back(vector) 
    vector=empty_vector 
t2=time.time() 

0.036sの代わりに、3S、この文脈で

+0

あなたが正しい軌道に乗っているのを見て嬉しいです。 'vector_resize(4)'を一番上で一度だけ実行した後、 'empty_vector'とa1/a2/a3/a4を削除することができます。 'ベクトル[0]。最初= numpy_array [i、0,0]'。 –

+0

コメントありがとう!私は.resize()メソッドを知らなかった! – jean

2

を参照してください。 C++では、ベクトルのベクトルは効率的ではありません。その代わりに、4x2構造体を作成してそれらの単一ベクトルを作成する必要があります。あるいは、C++のNumPy配列をNx4x2配列へのポインタとして直接使用することをお勧めします。つまり、データのコピーを不必要に停止しますが、必要な場合は、NxMx2ではなく固定のNx4x2構造にコピーします。

+0

私は答えをupvotedしかし、私ははるかに良い方法を見つけ、初期化の要因100を獲得した。 – jean

+0

私はおそらく後で構造体を調べるでしょう – jean

+0

可変サイズの構造体をベクター内に持つ理由がありますので、私は 'vector [vector [vector [vector]]を選択した' fixed_size_vector [(variable_sized_vector [(double、double)] 'ペア[ダブル、ダブル]]] ' – jean

関連する問題