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