2017-08-18 10 views
0

test2は、次のコードでtest1よりも高速ではありませんなぜ私は混乱しています:numpyで配列を事前に割り当てておくべきではないでしょうか?

くれた
import timeit 

setup = """ 
import numpy as np 
A = np.ones((220, 220, 220)) 
B = np.ones((220, 220, 220)) 

class store: 
    def __init__(self): 
     self.C = np.empty((220, 220, 220)) 
Z = store() 
""" 

test1 = """ 
C = A + B 
""" 

test2 = """ 
Z.C = A + B 
""" 

print timeit.timeit(test1, setup, number=1000) 
print timeit.timeit(test2, setup, number=1000) 

40.9241290092 40.7675480843

私はZ.Cがメモリを事前に割り当てられたために、少ないオーバーヘッド毎回私があるだろうと思いましたA+Bが追加されていて、それを保存する場所が必要でした。すなわち、mallocの裏側の電話などが少なくて済みました。私は何が欠けていますか?

+3

'ZC = A + B'は同じ配列を更新していないので、全く新しい割り当てです。 –

+0

ああ、Z.Cはいつも同じメモリアドレスではないのですが、それは既に割り当てられているZのメンバーなのですから? – NLi10Me

+1

'Z.C'は何もあらかじめ割り当てていませんが、今はnumpyの配列を指していて、後で文字列を指すことができます。新しいオブジェクトを指すと、それへの参照がなくなると古いオブジェクトがガベージコレクションされます。 –

答えて

0

割り当ては、ほかには、より高価な高速動作です:だから

In [7]: %timeit np.empty((220, 220, 220)) 
1000 loops, best of 3: 472 µs per loop 

In [8]: u= np.ones((220, 220, 220)) 

In [9]: %timeit u+u 
10 loops, best of 3: 73.5 ms per loop 

、も、あなたは正しく配列(Z.C[:]= A+B)あなたがあなたのケースで多くを獲得しませんを更新(〜0.5%)