閉じる

Bashのtimeコマンドで処理時間を計測する方法:実行時間やメモリ消費の確認手順

シェルスクリプトやコマンドの実行効率を改善するためには、まず現状の処理時間を正確に把握することが欠かせません。

特に大量のデータを扱う際や定期的に実行する自動化処理において、パフォーマンスのボトルネックを特定することは開発者の重要なスキルとなります。

Bash環境で手軽に、かつ詳細に実行時間を計測するための標準的な手段がtimeコマンドです。

本記事では、初心者の方でもすぐに使える基本的な実行方法から、メモリ消費量などの高度なリソース情報を取得する手順までを解説します。

効率的なスクリプト作成を目指して、timeコマンドの活用術をマスターしていきましょう。

timeコマンドの基本概要

Bashで利用できるtimeコマンドには、大きく分けて2つの種類が存在することをご存知でしょうか。

一つはBashに組み込まれている「シェル予約語」としてのtimeです。

もう一つは、多くのLinuxディストリビューションにインストールされている「外部コマンド(GNU版time)」である/usr/bin/timeです。

単にコマンドラインでtimeと入力して実行した場合は、通常Bashの組み込み版が優先的に動作します。

組み込み版は非常に高速で動作し、追加のパッケージインストールも不要であるため、簡易的な計測に最適です。

一方で、メモリの使用状況やI/O回数などのより詳細なシステムリソースの状態を確認したい場合は、外部コマンド版を使用する必要があります。

本記事では両者の違いについても触れながら、それぞれの計測手法を紹介していきます。

Bash組み込みtimeコマンドの使い方

まずは、最も手軽に利用できるBash組み込み版のtimeコマンドから解説します。

使い方は非常にシンプルで、計測したいコマンドの前にtimeを付けて実行するだけです。

Shell
# sleepコマンドで3秒間待機する処理を計測する
time sleep 3

実行後、標準エラー出力に計測結果が表示されます。

実行結果
real    0m3.002s
user    0m0.000s
sys     0m0.001s

このように、実行が完了すると「real」「user」「sys」という3つの項目が出力されます。

実行結果(real, user, sys)の意味

計測結果に表示される3つの項目には、それぞれ重要な意味があります。

real(実時間)は、コマンドの開始から終了までに実際にかかった「壁時計時間」を指します。

これには、CPUが処理を待っている時間や、入出力(I/O)の待ち時間もすべて含まれます。

ユーザーが体感する待ち時間は、このrealの値と一致します。

user(ユーザーCPU時間)は、プログラムがユーザーモードでCPUを直接使用した時間の合計です。

カーネル内での処理や、他のプロセスによる待ち時間は含まれません。

sys(システムCPU時間)は、プログラムの実行中にシステムコールなどのためにカーネル内で消費されたCPU時間を示します。

ファイルの読み書きやメモリ割り当てなど、OSに依頼した処理にかかった時間がここに反映されます。

「user + sys」の合計が、その処理が実際にCPUを稼働させていた総時間となります。

GNU版timeコマンドによる詳細な計測

Bash組み込み版では時間の計測しかできませんが、外部コマンドの/usr/bin/timeを使用するとより多くの情報を得られます。

外部コマンド版を明示的に呼び出すには、フルパスで指定するか、コマンドの前にバックスラッシュを付けて\timeと入力します。

Shell
# 外部コマンド版のtimeを使用して詳細情報を表示する
/usr/bin/time -v ls -R /etc > /dev/null

ここで使用している-v(verbose)オプションは、非常に強力な機能です。

実行結果には、時間以外にメモリ消費量やスワップ回数、コンテキストスイッチの回数などが詳細に出力されます。

実行結果
	Command being timed: "ls -R /etc"
	User time (seconds): 0.01
	System time (seconds): 0.02
	Percent of CPU this job got: 96%
	Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.03
	Average shared text size (kbytes): 0
	Average unshared data size (kbytes): 0
	Average stack size (kbytes): 0
	Average total size (kbytes): 0
	Maximum resident set size (kbytes): 4832
	Average resident set size (kbytes): 0
	Major (requiring I/O) page faults: 0
	Minor (reclaiming a frame) page faults: 825
	Voluntary contex switches: 1
	Involuntary context switches: 5
	Swaps: 0
	File system inputs: 0
	File system outputs: 0
	Socket messages sent: 0
	Socket messages received: 0
	Signals delivered: 0
	Page size (bytes): 4096
	Exit status: 0

メモリ消費量を確認する(Maximum resident set size)

多くのエンジニアが注目すべき項目は、Maximum resident set sizeです。

これは、プロセスが実行中に使用した最大メモリ量(物理メモリのピーク使用量)を表しています。

単位はキロバイト(kbytes)で表示されるため、必要に応じてメガバイト(MB)に換算して読み取ります。

プログラムがメモリリークを起こしていないか、あるいは想定以上のメモリを消費していないかをチェックする際に非常に役立ちます。

スクリプトが特定のデータサイズを超えた際に急激に重くなる場合、この数値を確認することでメモリ不足が原因かどうかを切り分けられます。

出力フォーマットのカスタマイズ

GNU版のtimeコマンドでは、必要な情報だけを抽出して表示するようにカスタマイズすることが可能です。

-f(format)オプションを使用することで、自由な形式で結果を出力できます。

Shell
# 実行時間と最大メモリ消費量だけを表示する設定
/usr/bin/time -f "実行時間: %E\n最大メモリ: %M KB\nCPU使用率: %P" sleep 1
実行結果
実行時間: 0:01.00
最大メモリ: 2144 KB
CPU使用率: 0%

使用できる主な書式指定子を以下の表にまとめました。

指定子説明
%E経過した実時間(Elapsed time)
%UユーザーCPU時間(User CPU time)
%SシステムCPU時間(System CPU time)
%M最大メモリ使用量(Maximum resident set size)
%PCPU使用率(Percentage of CPU)
%xコマンドの終了ステータス(Exit status)

このように必要な項目だけを絞り込むことで、ログの可読性を高めることができます。

計測結果をファイルに保存する

定期的なバッチ処理などで計測結果を記録しておきたい場合は、出力をファイルに保存する必要があります。

ただし、timeコマンドの計測結果は、通常の標準出力(stdout)ではなく標準エラー出力(stderr)に送られる点に注意が必要です。

GNU版のtimeコマンドには、出力を直接ファイルに書き出すための-o(output)オプションが用意されています。

Shell
# 計測結果を result.txt に書き込む
/usr/bin/time -o result.txt -v my_script.sh

既存のファイルに追記したい場合は、-a(append)オプションを併用します。

Shell
# 計測結果を既存のファイルに追記する
/usr/bin/time -a -o log.txt -f "Time: %E" my_script.sh

一方で、Bash組み込みのtimeの結果をリダイレクトする場合は、少し特殊な構文が必要です。

Bashのtimeはコマンド全体にかかる予約語であるため、単純なリダイレクトでは計測対象コマンドの出力だけが保存されてしまいます。

組み込み版の結果をファイルに保存するには、以下のようにサブシェルを利用して全体を括ります。

Shell
# サブシェルを使用して標準エラー出力をリダイレクトする
{ time my_script.sh ; } 2> time_log.txt

この記述方法により、計測対象コマンドの実行結果とtimeの結果を分離して制御することが可能になります。

正確な計測を行うための注意点

実行時間を計測する際には、いくつかの外的要因を考慮しなければなりません。

まず、ディスクキャッシュの影響に注意が必要です。

一度実行したコマンドやファイルを読み込んだ直後に再計測すると、データがOSのメモリ上にキャッシュされているため、2回目以降の実行時間が極端に短くなることがあります。

純粋なコールドスタート(初回実行時)の状態を計測したい場合は、キャッシュをクリアするか、マシンの再起動後に計測を行うのが理想的です。

また、システムの他の負荷状況にも影響を受けます。

バックグラウンドで別の重い処理が走っている場合、CPUリソースの奪い合いが発生し、realの時間が延びてしまいます。

精度の高い計測データを得るためには、複数回の試行を行い、その平均値を取ることを推奨します。

まとめ

Bashのtimeコマンドは、スクリプトのパフォーマンス分析において最も基本的かつ強力なツールです。

単なる実行時間の確認であればBash組み込み版で十分ですが、メモリ消費量や詳細な負荷状況を知りたい場合はGNU版の/usr/bin/timeを活用しましょう。

「real」「user」「sys」の違いを正しく理解することで、ボトルネックがCPUにあるのか、あるいはI/O待ちにあるのかを的確に判断できるようになります。

本記事で紹介したオプションやリダイレクトの手法を参考に、日々の開発やシステム運用における最適化に役立ててください。

計測を通じて得られたデータは、より高品質なプログラムを作成するための確かな指標となるはずです。

URLをコピーしました!