導入
Python 開発者として、私たちはコードの最適化について心配する前に、コードが機能することに重点を置くことがよくあります。ただし、大規模なアプリケーションやパフォーマンスが重要なコードを扱う場合は、最適化が重要になります。この投稿では、Python コードの最適化に使用できる 2 つの強力なツール、cProfile モジュールと PyPy インタープリターについて説明します。
この投稿を最後まで読むと、次のことがわかります:
- cProfile モジュールを使用してパフォーマンスのボトルネックを特定する方法。
- 速度を高めるためにコードを最適化する方法。
- PyPy を使用して、ジャストインタイム (JIT) コンパイルで Python プログラムをさらに高速化する方法。
パフォーマンスの最適化が重要な理由
Python は、使いやすさ、読みやすさ、ライブラリの広大なエコシステムで知られています。ただし、解釈される性質のため、C や Java などの他の言語よりも遅くなります。したがって、機械学習モデル、リアルタイム システム、高頻度取引システムなどのパフォーマンス重視のアプリケーションでは、Python コードを最適化する方法を知ることが重要になります。
最適化は通常、次の手順に従います:
-
コードをプロファイリングして、ボトルネックがどこにあるのかを理解します。
-
非効率な領域のコードを最適化します。
- 最適化されたコードを PyPy などの高速インタープリタで実行し、最大のパフォーマンスを実現します。
それでは、コードのプロファイリングから始めましょう。
ステップ 1: cProfile を使用してコードをプロファイリングする
cプロファイルとは何ですか?
cProfile は、パフォーマンス プロファイリング用の組み込み Python モジュールです。コード内の各関数の実行にかかる時間を追跡するため、速度低下の原因となっているコードの関数またはセクションを特定するのに役立ちます。
コマンドラインからの cProfile の使用
スクリプトをプロファイリングする最も簡単な方法は、コマンド ラインから cProfile を実行することです。たとえば、my_script.py:
というスクリプトがあるとします。
python -m cProfile -s 累積的な my_script.py
python -m cProfile -s cumulative my_script.py
説明:
-m cProfile: cProfile モジュールを Python の標準ライブラリの一部として実行します。-
-s 累積: 各関数に費やした累積時間によってプロファイリング結果を並べ替えます。-
my_script.py: Python スクリプト。-
これにより、コードが時間を費やしている場所の詳細な内訳が生成されます。
例: Python スクリプトのプロファイリング
フィボナッチ数を再帰的に計算する基本的な Python スクリプトを見てみましょう:
def フィボナッチ(n):
n python -m cProfile -s cumulative my_script.py
cProfile:
を使用してこのスクリプトを実行します
python -m cProfile -s 累積的な fibonacci_script.py
python -m cProfile -s cumulative my_script.py
cProfile の出力について
cProfile を実行すると、次のような内容が表示されます:
ncalls tottime percall cumtime percall filename:lineno(function)
8320 0.050 0.000 0.124 0.000 fibonacci_script.py:3(フィボナッチ)
python -m cProfile -s cumulative my_script.py
各列には主要なパフォーマンス データが表示されます:
- ncalls: 関数が呼び出された回数。
- tottime: 関数に費やした合計時間 (サブ関数を除く)。
- cumtime: 関数 (サブ関数を含む) で費やした累積時間。
- 通話ごと: 通話ごとの時間。
フィボナッチ関数に時間がかかりすぎる場合、この出力はどこに最適化の取り組みを集中すべきかを示します。
コードの特定部分のプロファイリング
特定のセクションのみをプロファイリングしたい場合は、コード内で cProfile をプログラム的に使用することもできます。
cProfile をインポート
デフォルトフィボナッチ(n):
n python -m cProfile -s cumulative my_script.py
ステップ 2: Python コードの最適化
cProfile を使用してコード内のボトルネックを特定したら、最適化します。
一般的な Python 最適化手法
- 組み込み関数を使用する: sum()、min()、max() などの組み込み関数は Python で高度に最適化されており、通常は手動で実装したループより高速です。
例:
# 前: カスタム合計ループ
合計 = 0
範囲 (1000000) 内の i の場合:
合計 = i
# 変更後: 組み込みの合計を使用する
合計 = 合計(範囲(1000000))
python -m cProfile -s cumulative my_script.py
- 不要な関数呼び出しを避ける: 関数呼び出しには、特にループ内でオーバーヘッドが発生します。冗長な呼び出しを減らすようにしてください。
例:
# 前: 不要な繰り返し計算
範囲 (1000) 内の i の場合:
print(len(my_list)) # len() が 1000 回呼び出されます
# 後: 一度計算して再利用
list_len = len(my_list)
範囲 (1000) 内の i の場合:
print(list_len)
python -m cProfile -s cumulative my_script.py
- メモ化: 再帰関数の場合、メモ化を使用して負荷の高い計算の結果を保存し、作業の繰り返しを避けることができます。
例:
functools インポート lru_cache から
@lru_cache(maxsize=なし)
デフォルトフィボナッチ(n):
n python -m cProfile -s cumulative my_script.py
これにより、各再帰呼び出しの結果が保存されるため、フィボナッチ計算が大幅に高速化されます。
ステップ 3: PyPy を使用したジャストインタイム コンパイル
ピピーとは何ですか?
PyPy は、ジャストインタイム (JIT) コンパイルを使用して Python コードを高速化する代替 Python インタープリターです。 PyPy は、頻繁に実行されるコード パスをマシン コードにコンパイルするため、特定のタスクでは標準の CPython インタープリターよりもはるかに高速になります。
PyPyのインストール
Linux の apt や macOS の brew などのパッケージ マネージャーを使用して PyPy をインストールできます:
# Ubuntu 上
sudo apt-get インストール pypy3
# macOS の場合 (Homebrew を使用)
醸造インストールpypy3
python -m cProfile -s cumulative my_script.py
PyPy を使用して Python コードを実行する
PyPy をインストールすると、CPython の代わりに PyPy を使用してスクリプトを実行できます:
pypy3 my_script.py
python -m cProfile -s cumulative my_script.py
PyPy を使用する理由
PyPy は、プログラムが計算 (ループ、再帰関数、数値処理など) にほとんどの時間を費やす - CPU に依存するタスクに最適です。
PyPy の JIT コンパイラは、最も頻繁に実行されるコード パスを最適化します。これにより、コードを変更せずに大幅な高速化が実現します。-
ステップ 4: cProfile と PyPy を組み合わせて最大限の最適化を図る
さあ、これらのツールを組み合わせて、Python コードを完全に最適化しましょう。
ワークフロー例
- cProfile を使用してコードをプロファイリングし、ボトルネックを特定します。
- これまで説明した手法 (組み込み、メモ化、不要な関数呼び出しの回避) を使用してコードを最適化します。
最適化されたコードを PyPy で実行- すると、さらにパフォーマンスが向上します。
フィボナッチの例をもう一度見て、すべてをまとめてみましょう。
functools から lru_cache をインポート
@lru_cache(maxsize=なし)
デフォルトフィボナッチ(n):
n
from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci(n):
if n
pypy3 fibonacci_script.py
pypy3 fibonacci_script.py
cProfile と PyPy を活用すると、Python コードを大幅に最適化できます。 cProfile を使用して、コード内のパフォーマンスのボトルネックを特定して対処します。次に、PyPy を使用して、JIT コンパイルを通じてプログラムの実行速度をさらに向上させます。
要約すれば:
cProfile を使用してコードをプロファイリングし、パフォーマンスのボトルネックを理解します。- 組み込みやメモ化の使用など、Python 最適化テクニックを適用します。
- PyPy で最適化されたコードを実行して、さらに優れたパフォーマンスを実現します。
-
このアプローチを使用すると、特に CPU に依存するタスクの場合、Python プログラムをより高速かつ効率的に実行できます。
連絡してください:
ギットハブ
リンクトイン