概要(timeit は「公平に何度も走らせて平均速度を測る」ための標準ツール)
timeit は、コードの実行時間を正確に測るための標準モジュールです。1回だけの計測はノイズに弱いので「複数回・同じ条件で」走らせて平均をとるのが基本設計。Jupyter、スクリプト、コマンドラインのどれでも使えます。重要なのは、測りたい“処理だけ”を切り出して、準備(セットアップ)と計測本体を分けることです。順序最適化と回数設定で再現性が高くなります。
基本の使い方(ここが重要)
スクリプトから timeit.timeit を使う
関数やスニペットを一定回数繰り返して、合計秒数を返します。処理が短いほど number を大きく、長いほど小さくします。
import timeit
code = "sum(range(1000))"
sec = timeit.timeit(code, number=10000)
print(sec) # 10000回合計の秒数(1回あたりは sec/number)
PythonPython の文字列として渡したコードは、現在のスコープの関数や変数を参照できるように globals を渡すと便利です。
import timeit
def f(n):
return sum(range(n))
sec = timeit.timeit("f(1000)", globals=globals(), number=10000)
print(sec)
Pythonセットアップと本体を分ける(初期化コストを外に出す)
準備に時間がかかる場合、set up で一度だけ実行し、計測本体では“純粋な処理”だけを測ります。
import timeit
setup = "data = list(range(1000))"
stmt = "sum(data)"
sec = timeit.timeit(stmt, setup=setup, number=100000)
print(sec)
Pythonコマンドラインから測る(-m timeit)
コマンドライン実行は短い比較に便利です。-n は1回の試行の実行回数、-r は試行の繰り返し回数で、最小値を報告します。
python -m timeit -n 100000 "sum(range(100))"
python -m timeit -n 1000 -r 7 -s "data=list(range(1000))" "sum(data)"
Python重要ポイントの深掘り(公平性・回数設定・計測の切り分け)
“測りたい処理だけ”を測定対象にする
計測対象に準備やI/Oが混ざると、純粋な計算速度が見えません。セットアップで一度準備し、本体は処理だけにします。これで比較が公平になります。
# 悪い例:準備も一緒に測ってしまう
timeit.timeit("data=list(range(1000)); sum(data)", number=100000)
# 良い例:準備を setup に分離
timeit.timeit("sum(data)", setup="data=list(range(1000))", number=100000)
Pythonnumber(回数)と r(反復)の考え方
処理が非常に高速なら number を増やして測定値を安定化します。遅い処理なら number を小さくして、r(反復)を増やし最良値を採用するとノイズに強くなります。1回あたりの平均時間は合計秒数を number で割って算出します。
sec = timeit.timeit("sum(range(1000))", number=10000)
avg = sec / 10000
print(avg, "秒/回")
Python比較は「同じセットアップ・同じ回数」で
比較したい候補間で setup と number を揃え、測定方法を同一にします。順序入れ替えや複数回の計測でばらつきを確認し、極端な外れ値は無視します。
実務の使いどころ(アルゴリズム比較・データ構造選定・マイクロ最適化)
アルゴリズム比較(内包表記 vs ループ)
同じ仕事をする2つの実装を、同一条件で比較します。差が小さいときは読みやすさ優先、差が大きいときは速い方を採用します。
import timeit
setup = "data=list(range(1000))"
c1 = timeit.timeit("[x*x for x in data]", setup=setup, number=5000)
c2 = timeit.timeit("""
out=[]
for x in data: out.append(x*x)
""", setup=setup, number=5000)
print("comp:", c1, "loop:", c2)
Pythonデータ構造選定(list vs deque の先頭取り出し)
操作の特性が速度に直結します。先頭操作は deque が強いことを数値で確認すると、選定が確信に変わります。
import timeit
setup_list = "from collections import deque; L=list(range(10000))"
stmt_list = "L.pop(0)"
setup_deque = "from collections import deque; D=deque(range(10000))"
stmt_deque = "D.popleft()"
t_list = timeit.timeit(stmt_list, setup=setup_list, number=10000)
t_deque = timeit.timeit(stmt_deque, setup=setup_deque, number=10000)
print("list pop(0):", t_list)
print("deque popleft():", t_deque)
Pythonキー計算の前取り(attrgetter/itemgetter の効果)
sorted の key をラムダから前取りへ変える効果を測って、読みやすさとのバランスを判断します。
import timeit
setup = """
from operator import itemgetter
rows=[('a', i) for i in range(1000)]
"""
s_lambda = "sorted(rows, key=lambda r: r[1])"
s_getter = "sorted(rows, key=itemgetter(1))"
t1 = timeit.timeit(s_lambda, setup=setup, number=5000)
t2 = timeit.timeit(s_getter, setup=setup, number=5000)
print("lambda:", t1, "itemgetter:", t2)
Pythonよくある落とし穴の回避(環境差・キャッシュ・I/O混在)
計測の再現性は“環境”に依存する
CPU負荷、バックグラウンドプロセス、電源設定で結果が揺れます。余計な負荷を減らし、同じ環境・同じ条件で複数回測定し、中央値や最小値を参考にします。
ウォームアップとキャッシュの影響を意識する
初回はインタプリタやモジュールの読み込み、キャッシュ未構築で遅くなることがあります。timeit は内部で繰り返すため自然に慣れますが、セットアップに import を入れておく、比較対象の順序を入れ替えると偏りを避けられます。
I/O を混ぜない(純粋な計算だけを測る)
ファイル・ネットワーク・print は環境差が大きく、計測ノイズになります。計算速度を測りたいなら I/O をセットアップに逃がすか、専用のベンチを用意します。
例題で身につける(定番から一歩先まで)
例題1:1回あたりの平均時間を出す
import timeit
sec = timeit.timeit("sum(range(1000))", number=10000)
print("total:", sec, "avg:", sec/10000)
Python例題2:関数を直接計測(callable を渡す)
文字列ではなく、callable を渡すとスコープ管理が簡単です。
import timeit
def task():
return sum(range(1000))
sec = timeit.timeit(task, number=10000)
print(sec)
Python例題3:複数行の処理を比較
import timeit
setup = "data=list(range(1000))"
A = """
total = 0
for x in data:
total += x
"""
B = "sum(data)"
tA = timeit.timeit(A, setup=setup, number=10000)
tB = timeit.timeit(B, setup=setup, number=10000)
print("loop:", tA, "sum:", tB)
Python例題4:Jupyter なら %%timeit マジックで手早く
# セルの先頭に書くと、そのセルのコードを自動で複数回計測
%%timeit
sum(range(1000))
Python計測回数やリピート回数は自動調整され、平均・標準偏差が表示されます。
まとめ
timeit は「同条件で何度も走らせ、純粋な処理だけを測って比較する」ための標準ツールです。セットアップと本体を分け、number と反復で安定化し、平均時間を算出する。比較は同じ条件で、公平に。I/Oや初期化を含めないことで“計算そのものの速さ”が見えます。アルゴリズム比較、データ構造選定、キー計算の前取りなど、迷ったら数値で決める癖をつける。測って、確かめて、最適化の手応えを得る—そのサイクルが、短くて速くて壊れないコードを作ります。

