💡
CythonによるPythonの高速化!!
公式やpipコマンドのご紹介
pip install Cython
ビルドする
1. 対象のPythonのコードを「pyx」で保存する。
test_cython.pyx
for i in range(1, 100000000):
i = i + 1
print(i)
2. setup.pyを作成する。
setup.py
from setuptools import setup
from Cython.Build import cythonize
setup(
ext_modules=cythonize("test_cython.pyx")
)
3.ビルドする。
python setup.py build_ext --inplace
⚠エラーが出た場合
error: Microsoft Visual C++ 14.0 is required. Get it with "Build Tools for Visual Studio": https://visualstudio.microsoft.com/downloads/
URLのページに進む
※筆者は簡単にインストールを済ませるために「C++によるデスクトップ開発」にチェックを入れてインストールを行いました。
ビルド完了後
buildフォルダが生成され、pydファイルとその他もろもろが生成されます。(Windowsの場合)
4.利用してみよう
test.py
import test_cython
実行コマンド
python test.py
うまくコマンドが実行できましたね。
速度の検証
上記のデコレータを使用して速度を比較してみましょう。
通常のPython
import pstats
import cProfile
def execution_speed_lib(func):
"""
実行速度計測用のデコレータ
"""
def wrapper(*args, **kwargs):
pr = cProfile.Profile()
# 実行処理の計測
pr.runcall(func, *args, **kwargs)
stats = pstats.Stats(pr)
stats.print_stats()
return wrapper
@execution_speed_lib
def run():
for i in range(1, 100000000):
i = i + 1
print(i)
run()
私の環境では5.349 ~ 5.44秒前後でした。
pydをimportするパターン
import pstats
import cProfile
def execution_speed_lib(func):
"""
実行速度計測用のデコレータ
"""
def wrapper(*args, **kwargs):
pr = cProfile.Profile()
# 実行処理の計測
pr.runcall(func, *args, **kwargs)
stats = pstats.Stats(pr)
stats.print_stats()
return wrapper
@execution_speed_lib
def run():
import test_cython
run()
こちらも5.44秒程度でした。速度はほぼ同じですね
ちなみに..test_cython.pyxの書き方を少し変えて再度ビルドしてみます。
test_cython.pyx
cdef int i
for i in range(1, 100000000):
i = i + 1
print(i)
結果
100000000
100 function calls in 0.011 seconds
Random listing order was used
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <frozen importlib._bootstrap_external>:36(_relax_case)
1 0.000 0.000 0.000 0.000 <frozen importlib._bootstrap>:58(__init__)
....
0.011秒になりました。速い...!!
cythonを利用する場合はかなり書き方に気を付けないと早くならないようですね。
他の関数やクラスでCythonを使用して爆速になった方は、コードとともに感想をお待ちしています。(すでに高速化されていいるnumpyはいったん見ないふりをしています。)
Discussion