いいえ、できません。あなたの興味深い例が指摘しているnumpy.sum
ように、最適ではない可能性があり、明示的な for ループを介した操作のより良いレイアウトはより効率的です。
別の例を示しましょう。
>>> N, M = 10**4, 10**4
>>> v = np.random.randn(N,M)
>>> r = np.empty(M)
>>> timeit.timeit('v.sum(axis=0, out=r)', 'from __main__ import v,r', number=1)
1.2837879657745361
>>> r = np.empty(N)
>>> timeit.timeit('v.sum(axis=1, out=r)', 'from __main__ import v,r', number=1)
0.09213519096374512
ここでnumpy.sum
は、高速実行インデックス ( v
C 連続) で合計する場合は最適であり、低速実行軸で合計する場合は最適ではないことが明確にわかります。興味深いことに、for
ループには逆のパターンが当てはまります。
>>> r = np.zeros(M)
>>> timeit.timeit('for row in v[:]: r += row', 'from __main__ import v,r', number=1)
0.11945700645446777
>>> r = np.zeros(N)
>>> timeit.timeit('for row in v.T[:]: r += row', 'from __main__ import v,r', number=1)
1.2647287845611572
コードを調べる時間はありませんでしたnumpy
が、違いを生んでいるのは、連続したメモリ アクセスまたはストライド アクセスであると思われます。
この例が示すように、数値アルゴリズムを実装する場合、正しいメモリ レイアウトは非常に重要です。ベクトル化されたコードがすべての問題を解決するとは限りません。