【Python time】入門:sleepでの待機からperf_counterでの正確な時間計測まで
PythonをコマンドプロンプトやPowerShellでPC上で動かすには、Pythonをダウンロードしてインストールする必要があります。
まだの方はPythonのインストールと開発環境の構築の記事を参考にして、Pythonをインストールしてください。
こんにちは!AIと一緒にプログラミングを学び、1ヶ月半で2つのWebサイトを立ち上げた専門家です。ほんの数ヶ月前まで、私も皆さんと同じプログラミング知識ゼロの初心者でした。
Pythonの学習を進めていると、AIが生成したコードや他の人のサンプルコードで頻繁に `import time` という記述を見かけませんか?「また `time` が出てきたけど、これって一体何ができるの?」「時間を止めたり、測ったりするだけ?」そう感じている方も多いかもしれません。
この記事では、そんな `time` モジュールについて、私が実際につまづいた経験も交えながら、初心者の方でも分かりやすいように噛み砕いて解説します。特に、Webサイト制作やデータ収集など、実践的な場面で必須となる「処理を一時停止する(スリープ)」方法と、「処理にかかった時間を正確に測る」方法に焦点を当てます。この記事を読み終える頃には、あなたも `time` モジュールを自在に操れるようになっているはずです!
1. なぜ「時間」の操作が必要なの? - 待つことの重要性
プログラムは速ければ速いほど良い、と思っていませんか?実は、時には「あえて待つ」ことが非常に重要になる場面があります。私がWebサイトを開発しているときに直面した、具体的な2つのケースをご紹介します。
ケース1:Webサイトからの情報収集(スクレイピング)
あるWebサイトから情報を自動で集めようとしたとき、プログラムは人間では考えられない速度で次々とページにアクセスします。すると、相手のサーバーに短時間で大量のアクセスが集中してしまい、大きな負荷をかけてしまうのです。これは、お店に大勢で押しかけて営業妨害をするようなもの。最悪の場合、アクセスをブロックされてしまうこともあります。
そこで役立つのが「待つ」技術です。1つのページにアクセスしたら数秒待つ、という処理を入れることで、サーバーへの負荷を大幅に軽減し、マナーを守った情報収集が可能になります。
ケース2:APIの利用
天気情報や地図情報などを提供してくれる外部のサービス(API)を利用する際にも、「時間」の管理は不可欠です。多くのAPIには、「1分間に60回まで」といった利用回数の制限(レートリミット)が設けられています。この制限を超えてリクエストを送ると、一時的にサービスが利用できなくなったり、エラーが返ってきたりします。
ここでも、リクエストを送るたびに一定時間「待つ」ことで、制限回数内に収めることができるのです。
このように、プログラムに意図的な「待ち時間」を設ける処理をスリープ処理と呼びます。そして、Pythonでこれを最も簡単に実現できるのが `time.sleep()` 関数です。
2. ピッタリ待機! `time.sleep()` で処理を一時停止する
`time.sleep()` は、指定した秒数だけプログラムの実行を一時的に停止させるとてもシンプルな関数です。まずは基本的な使い方を見ていきましょう。
以下のコードは、"処理を開始します。" と表示された3秒後に "3秒経過しました。処理を終了します。" と表示される簡単な例です。コピペして、ぜひお手元の環境で実行してみてください。「待つ」という感覚が掴めるはずです。
# timeモジュールをインポート
import time
print("処理を開始します。")
# 3秒間処理を停止
time.sleep(3)
print("3秒経過しました。処理を終了します。")
引数には、0.5(0.5秒)や 0.1(100ミリ秒)のように小数も指定できます。これにより、より細かな時間制御が可能です。
import time
print("0.5秒だけ待ちます。")
# 0.5秒間処理を停止
time.sleep(0.5)
print("完了!")
ループ処理と組み合わせると、定期的に何かを実行するプログラムも簡単に作れます。例えば、1秒ごとにカウントダウンするプログラムは次のようになります。
import time
print("カウントダウン開始!")
for i in range(5, 0, -1):
print(i)
# 1秒待つ
time.sleep(1)
print("発射!")
3. ストップウォッチ機能!処理時間を正確に測る方法
`time` モジュールのもう一つの重要な役割が、処理時間の計測です。自分の書いたコードのどの部分に時間がかかっているのかを把握することは、パフォーマンス改善の第一歩です。
「この処理、なんだか遅いな…」と感じたとき、感覚で判断するのではなく、実際に時間を測ってボトルネックを特定することが大切です。
初心者がやりがちな方法: `time.time()`
時間を測る最も基本的な方法は、処理の開始前と終了後で `time.time()` を呼び出し、その差分を計算することです。`time.time()` は、「UNIXエポック」と呼ばれる基準時刻(1970年1月1日0時0分0秒)からの経過秒数を返します。
import time
# 処理開始前の時刻を記録
start_time = time.time()
# ここに時間を計測したい処理を記述
# 例として、1秒待機する処理を入れてみる
print("計測中の処理を実行します...")
time.sleep(1)
print("処理が完了しました。")
# 処理終了後の時刻を記録
end_time = time.time()
# 経過時間を計算して表示
elapsed_time = end_time - start_time
print(f"処理にかかった時間: {elapsed_time} 秒")
【私の失敗談】 `time.time()` の落とし穴
実はこの `time.time()`、便利なのですが一つ大きな落とし穴があります。それは、PCのシステム時刻の変更に影響を受けてしまうということです。
私も学び始めの頃、長い時間かかる処理を `time.time()` で計測していました。しかし、処理の途中でPCが自動で時刻合わせ(NTP同期)を行ったため、実際の処理時間とは全く違う、おかしな結果が出てしまったことがあるのです。例えば、処理中に時刻が1秒巻き戻されると、計算上の経過時間が1秒短くなってしまいます。これでは正確な計測はできませんよね。
そこで登場するのが、より信頼性の高い時間計測の方法です。
プロが使う方法: `time.perf_counter()`
`time.perf_counter()`(performance counterの略)は、まさに処理時間の計測のような短時間の測定に特化した関数です。この関数が返す値は、具体的な「時刻」ではなく、OSが提供する最も精度の高い単調増加する時間です。
「単調増加」というのがポイントで、これはPCのシステム時刻が変更されても、決して逆戻りしないことを意味します。そのため、処理の途中で時刻同期が起きても、計測結果に影響を与えることはありません。
Pythonの公式ドキュメントでも、処理時間の計測には `perf_counter()` を使うことが推奨されています。
使い方は `time.time()` と全く同じです。
import time
# 処理開始前のカウンター値を記録
start_counter = time.perf_counter()
# ここに時間を計測したい処理を記述
print("計測中の処理を実行します...")
sum = 0
for i in range(10000000): # 時間のかかる処理の例
sum += i
print("処理が完了しました。")
# 処理終了後のカウンター値を記録
end_counter = time.perf_counter()
# 経過時間を計算して表示
elapsed_time = end_counter - start_counter
print(f"処理にかかった時間: {elapsed_time} 秒")
特別な理由がない限り、処理時間を計測する際は `time.perf_counter()` を使う、と覚えておけば間違いありません!
4. 【応用編】Webクリエーター向け!まるごと動くHTMLタイマー
これまでPythonの `time` モジュールについて学んできました。これらはサーバーサイド(裏側)で動くプログラムで非常に役立ちます。しかし、Webクリエーターとしては、その結果をユーザーが見える形、つまりWebページ上で表現したいですよね。
そこで、Pythonの `time` モジュールの考え方を応用して、ブラウザ上で動く簡単なカウントダウンタイマーをHTMLとJavaScriptで作ってみましょう。Pythonの `time.sleep(1)` が「1秒待つ」という命令だったように、JavaScriptでは `setInterval()` という命令を使うことで「1秒ごとに何かをする」が実現できます。
以下のコードは、HTMLファイルのすべてです。このコードをコピーして、`timer.html` のような名前で保存し、ブラウザで開いてみてください。ボタンを押すと、画面上の数字が1秒ごとに減っていくのが確認できるはずです。これこそ、ユーザーに「動く」を体験してもらう第一歩です!
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>カウントダウンタイマー</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #121212;
color: #e0e0e0;
font-family: sans-serif;
text-align: center;
}
#timer-display {
font-size: 8rem;
font-weight: bold;
color: #669df6;
}
button {
margin-top: 2rem;
padding: 1rem 2rem;
font-size: 1.5rem;
cursor: pointer;
border: 1px solid #5f6368;
background-color: transparent;
color: #8ab4f8;
border-radius: 5px;
}
button:disabled {
cursor: not-allowed;
opacity: 0.5;
}
</style>
</head>
<body>
<div>
<h1>JavaScriptで作るカウントダウン</h1>
<div id="timer-display">10</div>
<button id="start-btn">スタート</button>
<p>Pythonのtime.sleep()の考え方を応用!</p>
</div>
<script>
// scriptタグはここに記述します
const timerDisplay = document.getElementById('timer-display');
const startButton = document.getElementById('start-btn');
let timeLeft = 10;
let timerId = null;
function startTimer() {
// ボタンを無効化して二重クリックを防ぐ
startButton.disabled = true;
// 1秒ごと (1000ミリ秒) に処理を実行
timerId = setInterval(() => {
timeLeft--;
timerDisplay.textContent = timeLeft;
if (timeLeft <= 0) {
clearInterval(timerId); // タイマーを停止
timerDisplay.textContent = "Go!";
}
}, 1000);
}
// スタートボタンがクリックされたらタイマーを開始
startButton.addEventListener('click', startTimer);
</script>
</body>
</html>
5. `time` モジュールを使う上での注意点まとめ
最後に、`time` モジュールを扱う上での重要なポイントを再確認しておきましょう。
- スリープ処理には `time.sleep()`: WebスクレイピングやAPI利用時のマナーとして、処理を意図的に待たせたいときに使います。
- 時間計測には `time.perf_counter()`: 処理のパフォーマンスを正確に測りたいときに使います。PCの時刻変更に影響されないため、`time.time()` よりも信頼性が高いです。
- `sleep()` の精度は完璧ではない: `time.sleep(1)` としても、OSの他の処理の状況によっては、正確に1.000秒ではなく、1.002秒や1.01秒のようになる場合があります。超高精度な制御には向いていないことを覚えておきましょう。
まとめ
今回は、Pythonの `time` モジュールを使って、処理を「待たせる」方法と「測る」方法を学びました。一見地味なモジュールですが、実用的なプログラムを作る上では欠かせない、非常にパワフルなツールです。
特に `time.sleep()` は相手への配慮、`time.perf_counter()` は自分への配慮(コードのパフォーマンス改善)に繋がる大切な機能です。
今日学んだことを活かして、ぜひあなたのプログラムに「時間」という概念を取り入れてみてください。きっと、作れるものの幅がぐっと広がるはずです。
次のステップへ
`time`モジュールで時間の扱い方をマスターしたら、次はデータを効率的に扱うための便利なツールを学びませんか?Pythonには、標準で使える強力なデータ構造がまだまだたくさんあります。
次の記事では、`collections`モジュールに焦点を当て、辞書(dictionary)やリスト(list)をさらに便利にする`defaultdict`や`deque`といった機能を紹介します。これらを使いこなせば、より洗練されたコードが書けるようになりますよ!
» collectionsモジュールの便利なデータ構造まとめ