0Pricing
Python Academy · レッスン

C 拡張の理由: 用途とトレードオフ

ネイティブ C コードで Python を拡張するタイミングと理由を理解します。

「C 拡張の理由: 用途とトレードオフ」はCoddyKit上の無料Python Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPython Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Python Academyコースには全4レッスンが含まれています。

C拡張とは

C拡張は、Pythonからインポートできるコンパイル済み共有ライブラリです(Linux/macOSでは .so、Windowsでは .pyd)。Cで実装された関数や型を公開します。

# After building the extension:
import myext
result = myext.fast_sum([1, 2, 3, 4, 5])
print(result)   # 15 (computed in C)

C拡張を使う場面

CPU負荷の高い数値計算ループ、既存のCライブラリのラップ、マルチスレッド処理でのGILの回避、または極めて高いメモリ効率が必要な場合にC拡張を使用します。

# Good candidates for C extensions:
# - NumPy array operations
# - Image processing pixel loops
# - Cryptographic primitives
# - Wrapping libpng, libssl, sqlite3

C拡張の代替手段

Cを書く前に、Cython(アノテーション付きPythonからCへの変換)、Numba(JIT)、またはcffi/ctypes(既存のCライブラリを呼び出すための手段)を試してください。完全なC拡張は最も強力ですが、最も複雑な選択肢です。

# Cython example — almost Python syntax:
# def fast_sum(int[:] arr) -> int:
#     cdef int total = 0
#     for x in arr:
#         total += x
#     return total

GILに関する考慮事項

グローバルインタープリターロック(GIL)により、一度にPythonバイトコードを実行できるスレッドは1つだけです。C拡張は純粋なC処理中にGILを解放できるため、真のマルチスレッド並列処理が可能になります。

# In a C extension:
# Py_BEGIN_ALLOW_THREADS
#     result = heavy_cpu_work(data);
# Py_END_ALLOW_THREADS
#
# Other Python threads run while this C code executes

トレードオフ

C拡張は高速ですが、作成、デバッグ、保守がより困難です。Cの知識、ビルド基盤、プラットフォーム固有のテストが必要になります。

# Trade-offs:
# + Fastest possible execution
# + Direct access to C libraries
# + Can release GIL
# - Complex build setup (setup.py / CMake)
# - Platform-specific compilation
# - Memory management is manual
# - Harder to debug

Python/C APIの概要

Python/C APIは、Pythonオブジェクトの作成、参照カウントの操作、引数の解析、例外の発生、CからのPythonの呼び出しに使用するマクロと関数を提供します。

// C API basics:
// PyObject*  — pointer to any Python object
// Py_INCREF  — increment reference count
// Py_DECREF  — decrement reference count
// PyArg_ParseTuple — parse Python args from C
// PyErr_SetString  — raise a Python exception from C

setup.py のビルド

Extension オブジェクトを使用する setup.py で、C拡張をコンパイルしてインストールします。

# setup.py
from setuptools import setup, Extension

setup(
    name="myext",
    ext_modules=[
        Extension("myext", sources=["myext.c"])
    ]
)

# Build:
# python setup.py build_ext --inplace

実際の利用例

PythonエコシステムではC拡張が広く利用されています。NumPy、Pillow、lxml、PyYAML、および標準ライブラリの json、hashlib、zlib モジュールは、いずれもC拡張を使用しています。

# NumPy is a C extension:
import numpy as np
a = np.arange(1_000_000)
result = a.sum()   # executed in C, 100x faster than pure Python
print(result)

Cython:より簡単な方法

Cythonは、型などの注釈を付けたPythonコードをC拡張にコンパイルします。生のCコードを書く前に、まずCythonから始めてください。Cythonのほうがはるかに簡単で、多くの場合、速度の90%を実現できます。

# fib.pyx (Cython)
cpdef long fib(int n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

# Compile:
# cythonize -i fib.pyx
# import fib; fib.fib(40)

C拡張のデバッグ

C拡張のクラッシュをデバッグするには、gdbまたはlldbを使用します。CFLAGSで -g を有効にし、読みやすいスタックトレースを得るために最適化なしでコンパイルします。

# Compile with debug symbols:
# CFLAGS="-g -O0" python setup.py build_ext --inplace

# Debug:
# gdb python
# (gdb) run script.py
# (gdb) backtrace

# Valgrind for memory leaks:
# valgrind --tool=memcheck python script.py

C拡張のテスト

C拡張は、pytestを使用してPythonインターフェース経由でテストします。専用のCテストフレームワークは必要ありません。

# test_myext.py
import pytest
import myext

def test_fast_sum():
    assert myext.fast_sum([1, 2, 3]) == 6

def test_empty():
    assert myext.fast_sum([]) == 0

def test_type_error():
    with pytest.raises(TypeError):
        myext.fast_sum("not a list")

確認問題

純粋なPythonを使う代わりにC拡張を書く主な理由は何ですか?

まとめ

C拡張は、Pythonを高速化する最も速い方法です。ネイティブCコードを実行でき、GILを解放することもできます。既存のCライブラリを呼び出すにはctypes/cffi、注釈付きPythonコードをCにコンパイルするにはCythonを使用し、最大限の制御が必要な場合にのみ生のC拡張を使用してください。必ずPythonインターフェース経由でテストします。

よくある質問

「C 拡張の理由: 用途とトレードオフ」レッスンは無料ですか?

はい。「C 拡張の理由: 用途とトレードオフ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Python Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Python Academyコースには全4レッスンが含まれています。

「C 拡張の理由: 用途とトレードオフ」で何を学びますか?

ネイティブ C コードで Python を拡張するタイミングと理由を理解します。 ブラウザで直接実行するハンズオンコードでPython Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Python Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPython Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「C 拡張の理由: 用途とトレードオフ」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPython Academyレッスンでコードを書いて実行できますか?

はい。すべてのPython Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. C 拡張の理由: 用途とトレードオフ
  2. ctypes: Python から C ライブラリを呼び出す
  3. cffi: C 外部関数インターフェース
  4. Python C 拡張モジュールの作成
← Python Academyに戻る