Python Performance について
Python Performance は、Python 開発者向けのプロファイリングと最適化の学習資料です。ボトルネック分析、アルゴリズム、メモリ、高速化ライブラリ、並列処理を扱い、性能測定の実践課題も含みます。
主な機能
- 01CPU とメモリのプロファイリング
- 02アルゴリズムとデータ構造の最適化
- 03メモリ管理とリーク検出
- 04ベクトル化とコンパイル拡張
- 05並列処理とベンチマーク
活用シーン
- 01Python コードの性能ボトルネック特定
- 02大規模データ処理パイプラインの最適化
- 03実装方法ごとの実行時間比較
- 04計算負荷の高い処理の並列化設計
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ pluginagentmarketplace/ custom-plugin-python --skill python-performanceインストール後、Claude Code で/python-performanceを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/config.yamlreferences/GUIDE.mdscripts/helper.py詳細
Python のパフォーマンス最適化
概要
Python のパフォーマンス最適化を習得しましょう。コードのプロファイリング、ボトルネックの特定、アルゴリズムの最適化、メモリの効率的な管理、計算負荷の高いタスクでの高性能ライブラリの活用方法を学びます。
学習目標
- Python コードをプロファイリングしてボトルネックを特定する
- アルゴリズムとデータ構造を最適化する
- メモリを効率的に管理する
- コンパイル済み拡張機能(Cython、NumPy)を使用する
- キャッシュ戦略を実装する
- CPU バウンドな処理を並列化する
- ベンチマークを実施し、改善を測定する
主なトピック
1. プロファイリングとベンチマーク
- マイクロベンチマーク用の timeit モジュール
- 関数単位のプロファイリング用の cProfile
- 行単位の分析用の line_profiler
- メモリ使用量の計測用の memory_profiler
- 本番環境のプロファイリング用の py-spy
- フレームグラフと可視化
コード例:
import timeit
import cProfile
import pstats
# 1. timeit for micro-benchmarks
def list_comprehension():
return [x**2 for x in range(1000)]
def map_function():
return list(map(lambda x: x**2, range(1000)))
# Compare performance
time_lc = timeit.timeit(list_comprehension, number=10000)
time_map = timeit.timeit(map_function, number=10000)
print(f"List comprehension: {time_lc:.4f}s")
print(f"Map function: {time_map:.4f}s")
# 2. cProfile for function profiling
def process_data():
data = []
for i in range(100000):
data.append(i ** 2)
return sum(data)
profiler = cProfile.Profile()
profiler.enable()
result = process_data()
profiler.disable()
stats = pstats.Stats(profiler)
stats.sort_stats('cumulative')
stats.print_stats(10)
# 3. Line profiling (requires line_profiler package)
# @profile decorator (add manually for line_profiler)
def slow_function():
total = 0
for i in range(1000000):
total += i ** 2
return total
# Run with: kernprof -l -v script.py
# 4. Memory profiling
from memory_profiler import profile
@profile
def memory_intensive():
large_list = [i for i in range(1000000)]
large_dict = {i: i**2 for i in range(1000000)}
return len(large_list) + len(large_dict)
# Run with: python -m memory_profiler script.py
2. アルゴリズムとデータ構造の最適化
- 効率的なデータ構造の選択
- 時間計算量の分析
- ジェネレーター式とリストの比較
- 検索におけるセット操作
- キュー操作用の deque
- ソート済みリスト用の Bisect
コード例:
import bisect
from collections import deque, Counter, defaultdict
import time
# 1. List vs Set for membership testing
# Bad: O(n) lookup
def find_in_list(items, target):
return target in items # Linear search
# Good: O(1) lookup
def find_in_set(items, target):
items_set = set(items)
return target in items_set
items = list(range(100000))
# List: 0.001s, Set: 0.000001s (1000x faster!)
# 2. Generator expressions for memory efficiency
# Bad: Creates entire list in memory
squares_list = [x**2 for x in range(1000000)] # ~4MB
# Good: Generates on-demand
squares_gen = (x**2 for x in range(1000000)) # ~128 bytes
# 3. Deque for efficient queue operations
# Bad: O(n) pop from beginning
queue_list = list(range(10000))
queue_list.pop(0) # Slow
# Good: O(1) pop from both ends
queue_deque = deque(range(10000))
queue_deque.popleft() # Fast
# 4. Bisect for maintaining sorted lists
# Bad: O(n) insertion into sorted list
sorted_list = []
for i in [5, 2, 8, 1, 9]:
sorted_list.append(i)
sorted_list.sort()
# Good: O(log n) insertion
sorted_list = []
for i in [5, 2, 8, 1, 9]:
bisect.insort(sorted_list, i)
# 5. Counter for frequency counting
# Bad: Manual counting
word_count = {}
for word in words:
if word in word_count:
word_count[word] += 1
else:
word_count[word] = 1
# Good: Counter
word_count = Counter(words)
most_common = word_count.most_common(10)
3. メモリ管理
- メモリ割り当てとガベージコレクション
- オブジェクトプール
- メモリ効率の高いクラスのための Slots
- 参照カウント
- 弱参照
- メモリリークの検出
コード例:
import gc
import sys
from weakref import WeakValueDictionary
# 1. __slots__ for memory-efficient classes
# Bad: Regular class (56 bytes per instance)
class RegularPoint:
def __init__(self, x, y):
self.x = x
self.y = y
# Good: Slots class (32 bytes per instance - 43% smaller!)
class SlottedPoint:
__slots__ = ['x', 'y']
def __init__(self, x, y):
self.x = x
self.y = y
print(sys.getsizeof(RegularPoint(1, 2))) # 56 bytes
print(sys.getsizeof(SlottedPoint(1, 2))) # 32 bytes
# 2. Object pooling for expensive objects
class ObjectPool:
def __init__(self, factory, max_size=10):
self.factory = factory
self.max_size = max_size
self.pool = []
def acquire(self):
if self.pool:
return self.pool.pop()
return self.factory()
def release(self, obj):
if len(self.pool) < self.max_size:
self.pool.append(obj)
# Usage
db_pool = ObjectPool(lambda: DatabaseConnection(), max_size=5)
conn = db_pool.acquire()
# Use connection
db_pool.release(conn)
# 3. Weak references to prevent memory leaks
class Cache:
def __init__(self):
self._cache = WeakValueDictionary()
def get(self, key):
return self._cache.get(key)
def set(self, key, value):
self._cache[key] = value
# 4. Manual garbage collection for large operations
def process_large_dataset():
for batch in large_data:
process_batch(batch)
# Force garbage collection after each batch
gc.collect()
# 5. Context managers for resource cleanup
class ManagedResource:
def __enter__(self):
self.resource = allocate_resource()
return self.resource
def __exit__(self, exc_type, exc_val, exc_tb):
self.resource.cleanup()
return False
4. 高性能コンピューティング
- NumPy のベクトル化
- Numba の JIT コンパイル
- C 拡張機能向けの Cython
- 並列処理のための Multiprocessing
- Concurrent.futures
- パフォーマンスの比較
コード例:
import numpy as np
from numba import jit
import multiprocessing as mp
from concurrent.futures import ProcessPoolExecutor
# 1. NumPy vectorization
# Bad: Python loops (slow)
def python_sum(n):
total = 0
for i in range(n):
total += i ** 2
return total
# Good: NumPy vectorization (100x faster!)
def numpy_sum(n):
arr = np.arange(n)
return np.sum(arr ** 2)
# Benchmark: python_sum(1000000) = 0.15s
# numpy_sum(1000000) = 0.002s
# 2. Numba JIT compilation
@jit(nopython=True) # Compile to machine code
def fast_function(n):
total = 0
for i in range(n):
total += i ** 2
return total
# First call: compilation + execution
# Subsequent calls: 50x faster than pure Python!
# 3. Multiprocessing for CPU-bound tasks
def cpu_intensive_task(n):
return sum(i * i for i in range(n))
# Single process
result = cpu_intensive_task(10000000)
# Multiple processes
with ProcessPoolExecutor(max_workers=4) as executor:
ranges = [2500000, 2500000, 2500000, 2500000]
results = executor.map(cpu_intensive_task, ranges)
total = sum(results)
# 4x speedup on 4 cores!
# 4. Caching for expensive computations
from functools import lru_cache
@lru_cache(maxsize=128)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
# fibonacci(100) without cache: ~forever
# fibonacci(100) with cache: instant
# 5. Memory views for zero-copy operations
def process_array(data):
# Bad: Creates copy
subset = data[1000:2000]
# Good: Zero-copy view
view = memoryview(data)[1000:2000]
実践演習
プロジェクト 1:パフォーマンスプロファイラー
包括的なプロファイリングツールを構築します。
要件:
- cProfile による CPU プロファイリング
- メモリプロファイリング
- 行単位の分析
- 可視化(フレームグラフ)
- HTML レポートの生成
- ボトルネックの特定
主なスキル: プロファイリングツール、可視化、分析
プロジェクト 2:データ処理パイプライン
データ処理パイプラインを最適化します。
要件:
- 大容量の CSV ファイル(1GB 以上)を読み込む
- データを変換・クリーニングする
- 統計情報を集計する
- Python、NumPy、Pandas のアプローチを比較する
- メモリ使用量を測定する
- 使用メモリを 2GB 未満に最適化する
主なスキル: NumPy、メモリ最適化、ベンチマーク
プロジェクト 3:並列コンピューティング
並列アルゴリズムを実装します。
要件:
- 行列乗算
- 画像処理
- モンテカルロシミュレーション
- スレッド、マルチプロセス、asyncio を比較する
- 高速化率を測定する
- 共有状態を処理する
主なスキル: 並列処理、パフォーマンス測定
評価基準
- コードをプロファイリングしてボトルネックを特定する
- 適切なデータ構造を選択する
- 時間計算量を考慮してアルゴリズムを最適化する
- メモリを効率的に管理する
- 適用できる箇所でベクトル化を使用する
- 効果的なキャッシュを実装する
- CPU バウンドな処理を並列化する
リソース
公式ドキュメント
- Python のパフォーマンス向上のヒント - 公式のヒント
- NumPy ドキュメント - NumPy のドキュメント
- Numba ドキュメント - JIT コンパイル
学習プラットフォーム
- High Performance Python - O'Reilly の書籍
- Python Performance - Real Python のガイド
- Python の最適化 - PyCon の講演
ツール
- cProfile - CPU プロファイリング
- memory_profiler - メモリプロファイリング
- py-spy - サンプリングプロファイラー
- Scalene - CPU/GPU/メモリプロファイラー
次のステップ
Python のパフォーマンス最適化を習得したら、次の項目を学びましょう:
- Cython - Python 用の C 拡張機能
- PyPy - 代替 Python インタープリター
- Dask - 並列コンピューティングライブラリ
- CUDA - Python による GPU プログラミング
コメント
Markdown 対応