2016-12-13 8 views
2

これはキャッシュのことですが、時間が示唆していますか?NumPyでは、より大きな配列がより迅速に作成されますか?

In [55]: timeit a = zeros((10000, 400)) 
100 loops, best of 3: 3.11 ms per loop 

In [56]: timeit a = zeros((10000, 500)) 
The slowest run took 13.43 times longer than the fastest. This could mean that an intermediate result is being cached. 
100000 loops, best of 3: 3.43 µs per loop 

はそれをばかにしようとしましたが、それはうまくいきませんでした:

In [58]: timeit a = zeros((10000, 500+random.randint(100))) 
The slowest run took 13.31 times longer than the fastest. This could mean that an intermediate result is being cached. 
100000 loops, best of 3: 4.35 µs per loop 
+0

私は100000ループを取得し、多分、時間、3の最高:ループあたり4.57マイクロ秒 100000ループ、3の最高:ループあたり4.64マイクロ秒あなたのコードを実行するとその差は最小です – EdChum

+0

代わりに 'ones'を試してください。あるいは、 'fill'を追加します。 – hpaulj

+0

これは私のマシンでは一貫しています。 「ones」を使用すると両方のサイズが遅く(3〜4ms)なります。 – Bach

答えて

2

理由がキャッシュされていませんが、それnumpyのはだけではなく、完全な配列のプレースホルダを作成します。これは簡単に、あなたがこのような何かをするとき、あなたのRAMの使用状況を監視することで確認できます。

a = np.zeros((20000, 20000), np.float64) 

これは、自分のコンピュータ上の20k * 20kの* 8バイト〜3ギガバイトを割り当てません(ただし、np.zerosが使用しているため、OSに依存するかもしれませんC機能calloc)。しかし、この配列のほとんどの操作(たとえばa += 5)が即座にそのメモリを割り当てるため、注意してください!あなたはあなたのRAMに比べて適切なサイズを使用することを忘れないでください。

最後に、これは配列の割り当てを延期するだけで、それを操作するとすぐに割り当てと操作の組み合わせのタイミングは予想どおりになります(要素の数に比例します)。あなたが、ブロックはtimeit %%timeitを使用することができますので、あなたはIPythonを使用しているようだ:

%%timeit 
a = np.zeros((10000, 400)) 
a += 10 
# => 10 loops, best of 3: 30.3 ms per loop 

%%timeit 
a = np.zeros((10000, 800)) 
a += 10 
# => 10 loops, best of 3: 60.2 ms per loop 
+0

すばらしい説明!!これは本当にそうだ。 – Bach

+0

このプレースホルダは実際には非常に良いことに注意してください。巨大な配列(例えば)を作成した後に[0,0]にしか触れないと、時間がかかりません(配列の残りの部分にメモリを割り当てません)。サイズのしきい値がPython内から設定可能かどうかは疑問です。 – Bach

+0

私はnumpyのソースコードでスレッシュホールドを見つけようとしましたが、見つけられませんでした。この最適化を行う 'calloc'でもよいことに注意してください。どちらの方法でも、 'C'ファイル内にある可能性が高いので、Python内から簡単に変更することはできません。 – MSeifert

関連する問題