は、それらの実行タイミングと同じ整数入力 Numba Cythonループ最適化VS
def python(n):
total = 0
for m in range(1,n+1):
total += m
return total
from numba import jit
numba = jit(python)
cpdef int cython(int n):
cdef int total = 0
cdef int m
for m in range(1, n+1):
total += m
return total
def smart(n):
return n * (n + 1) // 2
が与えられたとき私は発見し幾分驚いた同じ応答を計算し、次の4つの機能(
python
、
numba
、
cython
と
smart
)を考えます
numba
のランタイムはn
とは無関係である(cython
ながら 'sはn
に線形である)numba
はsmart
これはすぐに二つの質問を提起するより遅いです:
- なぜNumbaがあるが、ないCython、一定の時間アルゴリズムにそれを回すことができますか?
- Numba がの場合、contstant-timeアルゴリズムに変換できますが、純粋なPythonの一定時間関数
smart
より遅いのはなぜですか?
私はアセンブラMavenを午前ないので、生成されたコードを見ると、本当に含有するように(ただし、私が誤解しているかもしれない)Numbaによって生成された中間LLVMのコードがまだ表示されていることを超えて、手がかりの私はあまり与えませんループ...と私は絶望的に最終的にそれから生成されるx64で失われる。 (誰かが聞いていない限り、生成されたコードはかなり長いので投稿しません)
私はこれをx64 LinuxでJupyterノートブックで実行しています。したがって、CythonがGCC 4.4を使用していると思われます。 Pythonをコンパイルするために使用された7。 llvmlite 0.20.0は、LLVM 4.0.xを意味します。
編集:
Iは
smart_numba = jit(smart)
と
cpdef int smart_cython(int n):
return n * (n + 1) // 2
smart_numba
とnumba
smart
(純粋パイソン)より 25%遅い同じタイミングを与えるのにもタイミングましたsmart_cython
より175%遅い。
これは、Numbaが貧弱な仕事をしているのに対し、CythonはPython /低レベルの境界を効率的に越えていることを示していますか?それとも何か他にはありますか?
はい、ゴッドボルトはループの不在/存在をかなり明確にします。しかし、私は32ビットであると理解している 'e'で始まるレジスタの使用によって混乱します。 Numbaは 'int64'を間違いなく推論しました。 'int'を' long int'に変更すると、解読能力を超えて、clangの出力が非常に長く複雑になります。興味深いことに、あなたのマシンのnumbaは、スマートより速いです:私の場合、25%**遅い**です。 Numbaは 'numba'のスピードに合わせて' smart'を遅くします( 'numba'が' smart'よりも遅いことを見ても驚くことではありません)。 – jacg
申し訳ありませんが誤って、私は有意に_slower_を意味しませんでした。編集を参照してください、それはタイプディスパッチが実際にはnumbaバージョンのオーバーヘッドを作成するものであるようです。 – chrisb