Pythonでのパフォーマンス。 簡単な方法

Pythonの利点の1つは、Cコードの最も抑制的な部分を書き換えて、プログラムの速度を達成できない解釈された言語の高さまで上げることができることです。 しかし、私は自分で試したことがない 複雑すぎると思った。 この記事を読んだ後、私はもうそうは思わない。



ctypesに精通しているプログラマーがここで興味深いものを見つけることはまずありませんが、初心者にはcatを求めます。



Ctypesは、外部ライブラリから関数をインポートするためのPythonメカニズムです。

%timeit -Pythonで式の実行時間を測定するIPythonシェルマジック関数




Ctypesは素晴らしいです! ちょっとした簡単な例から始めましょう。ある範囲の数値を合計します。

Pythonでのこの関数の実装を次に示します

def sumrange(arg): return sum(xrange(arg))
      
      





いいね! しかし、たとえば0〜10 ** 8(つまり、100,000,000)のように、非常に広い範囲の数値を要約しようとするとどうなるでしょうか。

 In [2]: %timeit sumrange(10**2) 1000000 loops, best of 3: 1.53 us per loop In [3]: %timeit sumrange(10**8) 1 loops, best of 3: 9.77 s per loop In [4]: %timeit sumrange(10**9) 1 loops, best of 3: 97.8 s per loop
      
      





もうそんなに楽しくない。 他のことを試してみましょう:

 def sumrange2(arg): x = i = 0 while i < arg: x += i i += 1 return x
      
      





何が来るのでしょうか?

 In [10]: %timeit sumrange2(10**2) 100000 loops, best of 3: 10.5 us per loop In [11]: %timeit sumrange2(10**8) 1 loops, best of 3: 18.5 s per loop
      
      





わあ...とても悪い...今回は10 ** 9も試しません。

それでは、どのように実行をスピードアップしますか? 数学的な最適化を提供しないでください...私たちはコンピューターの新しい世界にいます! ( 元の:数学のトリックを提案しないでください...これがコンピューティングの新しい世界です!

はい、アルゴリズムの複雑さは定数であり、引数の値n *(n + 1)/ 2に依存しないことを知っています。 しかし、記事はこれに専念していません。



ctypesはどうですか?



 #include <stdio.h> unsigned long long sumrange(unsigned long long arg) { unsigned long long i, x; x = 0; for (i = 0; i < arg; i++) { x = x + i; } return x; }
      
      





sumrange.cという名前で保存してコンパイルします(実験の純度のために最適化は使用しません):

$ gcc -shared -Wl,-install_name,sumrange.so -o sumrange.so -fPIC sumrange.c







何が起こったかをPythonにインポートします。

 import ctypes sumrange_ctypes = ctypes.CDLL('./sumrange.so').sumrange sumrange_ctypes.restype = ctypes.c_ulonglong sumrange_ctypes.argtypes = ctypes.c_ulonglong,
      
      







そしてオスカーは...



 In [15]: %timeit sumrange_ctypes(10**2) 1000000 loops, best of 3: 1.28 us per loop In [16]: %timeit sumrange_ctypes(10**8) 1 loops, best of 3: 381 ms per loop In [17]: %timeit sumrange_ctypes(10**9) 1 loops, best of 3: 3.79 s per loop In [18]: %timeit sumrange_ctypes(10**10) 1 loops, best of 3: 37.8 s per loop
      
      







サマリーサマリー:

10 ** 2 10 ** 8 10 ** 9 10 ** 10
ピュアPythonメソッド#1 1.53μs 9.77秒 97.8秒 -
ピュアPythonメソッド2 10.5μs 18.5秒 - -
ctypes 1.28μs 381ミリ秒 3.79秒 37.8秒




圧倒的なパフォーマンスの向上!



Node.jsハッカーには、同等のctypesがあります-FFI (Foreign Function Interface): github.com/rbranson/node-ffi



All Articles