8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Cythonとは

Cythonは、PythonをC言語にコンパイルして高速化するツール。

Pythonの構文を維持しながら、C言語の速度を得られる。「Python遅い」問題の切り札だよ。

Python → Cython → C → コンパイル → 高速な拡張モジュール

インストール

pip install cython

基本的な使い方

1. .pyxファイルを作成

# example.pyx

def python_style(n):
    """普通のPython関数"""
    total = 0
    for i in range(n):
        total += i
    return total

cpdef long cython_style(long n):
    """型宣言した高速版"""
    cdef long total = 0
    cdef long i
    for i in range(n):
        total += i
    return total

2. setup.pyでビルド

# setup.py
from setuptools import setup
from Cython.Build import cythonize

setup(
    ext_modules=cythonize("example.pyx")
)

3. コンパイル

python setup.py build_ext --inplace

4. 使用

from example import cython_style
result = cython_style(100_000_000)

型宣言

Cythonの高速化の鍵は型宣言です。

変数の型宣言

# cdef で型を宣言
cdef int x = 10
cdef double y = 3.14
cdef long z = 1000000000

# 配列
cdef int arr[100]

# ポインタ
cdef int* ptr

関数の型宣言

# def: Pythonから呼べる(遅い)
def python_func(x):
    return x * 2

# cdef: Cython/Cからのみ呼べる(速い)
cdef int c_func(int x):
    return x * 2

# cpdef: 両方から呼べる(中間)
cpdef int hybrid_func(int x):
    return x * 2

型一覧

Cython型 C型 用途
int int 整数
long long 長整数
float float 浮動小数点
double double 倍精度
bint int ブール値
char char 文字
str PyObject* 文字列

パフォーマンス比較

Pure Python vs Cython

処理 Pure Python Cython 高速化
単純ループ(1億回) 3.87秒 0.08秒 48x
フィボナッチ(35) 1.39秒 0.02秒 70x
素数カウント 0.11秒 0.005秒 22x

実践例

フィボナッチ

# fib.pyx

# Pure Python(遅い)
def fib_python(n):
    if n <= 1:
        return n
    return fib_python(n-1) + fib_python(n-2)

# Cython(速い)
cpdef long fib_cython(int n):
    if n <= 1:
        return n
    return fib_cython(n-1) + fib_cython(n-2)

素数判定

# primes.pyx

cpdef bint is_prime(int n):
    cdef int i
    if n < 2:
        return False
    for i in range(2, <int>(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

cpdef list get_primes(int limit):
    cdef int n
    cdef list primes = []
    for n in range(2, limit):
        if is_prime(n):
            primes.append(n)
    return primes

NumPy連携

# numpy_example.pyx
import numpy as np
cimport numpy as np
cimport cython

@cython.boundscheck(False)  # 境界チェック無効
@cython.wraparound(False)   # 負のインデックス無効
cpdef double array_sum(np.ndarray[np.float64_t, ndim=1] arr):
    cdef Py_ssize_t i
    cdef double total = 0.0
    for i in range(arr.shape[0]):
        total += arr[i]
    return total

Pure Pythonモード

.pyファイルでも型ヒントでCython高速化:

# example.py
import cython

@cython.cfunc
@cython.locals(n=cython.int, total=cython.long, i=cython.long)
def fast_sum(n: int) -> int:
    total: int = 0
    for i in range(n):
        total += i
    return total

コンパイルオプション

ディレクティブ

# cython: boundscheck=False
# cython: wraparound=False
# cython: cdivision=True
# cython: profile=True

または関数単位で:

@cython.boundscheck(False)
@cython.wraparound(False)
cpdef int fast_func(int n):
    ...
ディレクティブ 効果
boundscheck(False) 配列境界チェック無効
wraparound(False) 負のインデックス無効
cdivision(True) Cスタイル除算
profile(True) プロファイリング有効

pyximport

開発中は自動コンパイル:

import pyximport
pyximport.install()

import my_module  # .pyxを自動コンパイル

いつCythonを使うか

✓ 適している場面

  • 数値計算のループ
  • 再帰関数
  • NumPy配列の要素単位操作
  • C言語ライブラリのラッパー

✗ 向いていない場面

  • I/O処理(ファイル、ネットワーク)
  • 文字列操作が多い処理
  • Pythonオブジェクトを多用する処理

まとめ

Pure Python → Cython変換の手順:

1. .pyx ファイルを作成
2. 変数に cdef で型を付ける
3. 関数を cpdef に変更
4. setup.py でビルド
5. import して使用

型宣言するだけで10〜100倍の高速化!

ボトルネックの関数だけCython化するのが効率的です。

8
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?