Python入門トップページ


目次

  1. 平方根のリストを作成するプログラムを作成しよう
  2. 平方根のリスト作成プログラムを関数化しよう
  3. Cython で平方根リスト作成プログラムを高速化しよう

Cython を使って Python プログラムを高速化しよう

Cython で平方根リスト作成プログラムを高速化しよう

ここでは,前のページと同じように,0から1億までの平方根を格納するリストを作成し,その中から 4,084,441 の平方根を返すモジュールを作成します.これを Cython によって C言語のプログラムに変換してコンパイルする方法を説明します.

まず,Cython のバージョン 3 系の最新版をインストールします.最新版がわからない場合は次のように Cython==3 とだけ指定してインストールを試みます.するとエラーが表示され,インストール可能なバージョンが一覧で表示されるので,その最新版を利用すると良いでしょう.

% pip install Cython==3 ⏎
ERROR: Could not find a version that satisfies the requirement Cython==3 (from versions: 0.9.6.5, ...(中略)... 0.29.34, 3.0a1, 3.0a2, 3.0a3, 3.0a4, 3.0a5, 3.0a6, 3.0a7, 3.0.0a8, 3.0.0a9, 3.0.0a10, 3.0.0a11, 3.0.0b1, 3.0.0b2)
ERROR: No matching distribution found for Cython==3

実験時点での最新バージョンは上の通り,3.0.0b2だったので,そのバージョンを指定してインストールを行います.インストール後にはインストールされたバージョンを確認すると良いでしょう.

% pip install Cython==3.0.0b2 ⏎
% cython -V ⏎
Cython version 3.0.0b2
%

任意の名前でフォルダを作成し,そのフォルダの中に sqrtlist.pyx というファイルを作成します.つまり,前のページ からはファイルの拡張子が .py から .pyx に変わりましたが,ファイルの中身は同一です.

sqrtlist.pyx
import math

def sqrtlist(n):
    y = [0] * (n+1)
    for i in range(0, n+1):
        y[i] = math.sqrt(i)
    return y[4_084_441]

コンパイするための setup.py を同じフォルダに作成します.なお,4行目ではコンパイルしたいファイル名を指定していることに注意してください.

setup.py
from distutils.core import setup
from Cython.Build import cythonize

setup(ext_modules=cythonize(['sqrtlist.pyx']))

次のコマンドでコンパイルを実行します.コンパイルによって,.pyx ファイルが C言語に変換されて .c ファイルが作成されます.その後 .c がコンパイルされて .so ファイルが生成されます.

% ls ⏎
setup.py    sqrtlist.pyx
% python3 setup.py build_ext --inplace ⏎
Compiling sqrtlist.pyx because it changed.
[1/1] Cythonizing sqrtlist.pyx
...(中略)
copying build/lib.macosx-10.9-x86_64-3.9/sqrtlist.cpython-39-darwin.so ->
%

lsコマンドでファイルができたことを確認します.

% ls ⏎
build     sqrtlist.c    sqrtlist.pyx
setup.py  sqrtlist.cpython-39-darwin.so
%

sqrtlist モジュールを呼び出すメインプログラムを作成します.これも前のページの main.py と全く同じ内容です(ファイル名も同一で構いません).

main_cython.py
from sqrtlist import sqrtlist
import time

time_start = time.time()
n = 100_000_000
s = sqrtlist(n)
print(s)
time_end = time.time()
time_gap = time_end - time_start
print(f"処理時間は {time_gap:.2f} 秒でした")

ファイルのリストを確認して実行します.

% ls ⏎
build           setup.py    sqrtlist.cpython-39-darwin.so
main_cython.py  sqrtlist.c  sqrtlist.pyx
% python main_cython.py ⏎
2021.0
処理時間は 10.34 秒でした
% python main_cython.py ⏎
2021.0
処理時間は 10.36 秒でした
% python main_cython.py ⏎
2021.0
処理時間は 10.12 秒でした
%

上の通り,3回実行した結果,平均処理時間は 10.27 秒となり,処理速度はおよそ 1.42 倍になりました.

なお,コンパイルしてしまえば .so ファイルとそれを呼び出すメインの .py ファイルだけで動作します.ただし,Intel mac でコンパイルした .so は M1/M2 mac では動作しないことに注意してください.

% ls ⏎
main_cython.py  sqrtlist.cpython-39-darwin.so
% python main_cython.py ⏎
2021.0
処理時間は 10.90 秒でした
%

目次に戻る