UNIX/Linuxの部屋 timeコマンドの使い方

TOP UNIX/Linuxの部屋 UNIX/Linuxコマンド一覧 用語集 新版 由来/読み方辞書 環境変数マニュアル Cシェル変数 システム設定ファイル システムコール・ライブラリ ネットワークプログラミングの基礎知識 クラウドサービス徹底比較・徹底解説




コマンド time コマンド・プログラムの実行時間を計測する このエントリーをはてなブックマークに追加

最終更新


UNIX/Linux における time コマンドは、コマンドの実行時間を計測するためのコマンドである。また、ユーザ時間・システム時間など、どこで時間を費やしたかなどの情報を得ることができる
シェルの内部コマンドと /usr/bin/time などの外部コマンドで挙動が異なるので、注意が必要。


いろいろな time コマンド
上で、シェルの内部コマンドと /usr/bin/time などの外部コマンドがあると書いたが、実際はより複雑で、下記のような time コマンドが存在する。
  • シェルの内部コマンド
  • csh・tcsh 内部コマンドの time
  • bash 内部コマンドの time
  • その他シェル (zsh など) の 内部コマンドの time
なお、Bourne シェル (FreeBSD の sh である ash や、Ubuntu などの sh である dash など) には内部コマンドの time はない。
  • 外部コマンド
  • BSD time
  • GNU time (Coreutils などには含まれておらず、GNU time として配布されている)
  • その他 OS の time (Solaris など)

特にシェルスクリプトから time コマンドを実行する場合、Ubuntu で /bin/sh を使ったシェルスクリプトを書き、なおかつ GNU time をインストールしていなかったりすると time コマンドが存在せずエラーになるので、下記でどこにどんな time コマンドがあるか事前に把握しておこう。

csh・tcsh の場合:
% where time
time is a shell built-in
/usr/bin/time
bash の場合:
$ type -a time
time is a shell keyword
time is /usr/bin/time

time コマンドの基本的な使い方
time の引数にコマンド名を渡すと、そのコマンドを実行し、実行終了までにかかった時間を表示してくれる。
% time command

real 0m1.070s
⇒ command の実行に 1.07 秒かかったことがわかる。
user 0m0.020s
sys 0m0.010s

time コマンドの出力結果の解説
それぞれの time コマンドで、出力内容に若干の差異がある。まずは、出力がシンプルな BSD の time と、bash 内部コマンドの time を見てみよう。

BSD の /usr/bin/time の場合
% /usr/bin/time command
1.07 real 0.02 user 0.01 sys
bash 内部コマンドの time の場合
% time command

real 0m1.070s
user 0m0.020s
sys 0m0.010s

若干表記は異なるが、内容は同じである。
real とは、command の実行にかかった実際の時間を指す。この場合は 0.07秒。
user は、command の実行中、ユーザモードだった時間を指す。この場合は 0.02秒。
sys は、command の実行中、カーネルモードだった時間を指す。この場合は 0.01秒。

ユーザモードというのは、加算や減算、メモリへのアクセスなどを指す。for (i=0 ; ; i++) でループしたり、ライブラリルーチンである sprintf(3) や sin(3) など、そのプロセスのメモリ操作で完結する処理がこれにあたる。

カーネルモードとは、システムコールを実行したときのモード。マニュアルのセクション2 にある open、close、read、write、ioctl などがこれにあたる。ただし、ディスクなど I/O の待ち時間や、sleep 中など、CPU が割り当たっていない間の時間は含まれない。

例えばファイルへの出力のためにライブラリルーチンの fprintf(3) を呼び出した場合、プロセス内部で文字列を作成したり、stdio でメモリ上にバッファリングする部分はユーザモード、その後 write(2) を呼んだ後はカーネルモードとなる。I/O 待ちは user や sys にはカウントされない。

それぞれの値の関係性は
real = user + sys + I/O 待ち時間
である。ただしマルチコア CPU だと user と sys が real を超える可能性がある。

以下は I/O 回数などを表示しているため、より複雑な出力になっている。ただし、いずれも real・user・sys に相当する時間は出力されている。

csh・tcsh 内部コマンドの time の場合
% time find . -name a
0.030u 0.249s 0:05.02 5.3% 32+293k 341+8io 4pf+0w
⇒ find . -name a というコマンドの実行には 5.02 秒かかり、そのうちユーザモードで 0.030 秒、カーネルモードで 0.249 秒消費した。ファイルシステムからの読み込みが 341 回、書き込みが 8 回行われた。
GNU の time の場合
% /usr/bin/time sleep 2
0.01user 0.03system 0:02.01elapsed 1%CPU (0avgtext+0avgdata 600maxresident)k
24inputs+0outputs (1major+178minor)pagefaults 0swaps
⇒ ユーザモードが 0.01秒、カーネルモードが 0.03 秒、実時間は 2.01 秒。(ユーザモード + カーネルモード)÷実時間 は 1%。avetext は共有テキストの平均サイズ (KB)、avgdata は非共有データ領域の平均サイズ (KB)。maxresident は最大の RSS (KB)。24回のファイルからの入力、0回のファイルへの出力。1回のメジャーページフォルト (ディスクからの読み込み発生)、178回のマイナーページフォルト (メモリ上で完結)。0回のスワップ。

複数コマンド実行の計測
コマンドを
% command1; command2; command3
などと複数並べたときに全体の時間を継続したい場合、bash の内部コマンド time ならば、下記のように全体を計測することができる。
% time (sleep 1; sleep 2)
real 0m3.003s
user 0m0.000s
sys 0m0.002s
bash スクリプトであれば下記のように関数化してもよい。
#!/bin/bash
mysleep () {
sleep 1;
sleep 2;
}
time mysleep
それ以外の time では簡単な方法はないので、複数コマンドをシェルスクリプトにしたり、下記のように他のシェルにまかせよう。
/usr/bin/time sh -c "sleep 1;sleep 2"

なお、bash の内部コマンド time のみ、下記のようにパイプでつなぐと一連のコマンド実行をまとめて計測してくれる。
% time sleep 1 | sleep 3
real 0m3.021s
user 0m0.000s
sys 0m0.001s

time 実行結果のリダイレクト
外部コマンドの time は結果を標準エラー出力に出力するので、標準エラー出力をリダイレクトすればよい。
シェル内部コマンドの time は、csh・tcsh・bash ともリダイレクトすることができないので、サブシェルを使うしかないようである。
% (time sleep 1) >& time.out
→ csh・tcsh の場合
% (time sleep 1) 2> time.out
→ bash の場合

time コマンドと SIGINFO シグナルによる途中経過の把握
BSD の time コマンドには SIGINFO シグナルを受け取ると現在の状況を表示する機能がある。
% /usr/bin/time sleep 100 &
[1] 70664
→ time コマンドをバックグラウンドで実行。
% ps aux|grep 70664
68user 70664 0.0 0.2 6244 2008 0 S 20:55 0:00.01 /usr/bin/time sleep 100
→ time コマンドはプロセス ID 70664 で実行中。
% kill -INFO 70664
18.08 real 0.00 user 0.00 sys
→ time コマンドに対して SIGINFO を送ると、その時点での状況を表示する。time と sleep は動きつづける。
100.00 real 0.00 user 0.00 sys
→ sleep コマンドが終了すると、time コマンドは最終的な結果を表示する。

関連コマンド
日時・時刻の表示や現在時刻の設定には date コマンドを使う。
>> Solaris10オンラインマニュアル(man) Solaris10 time(1)
>> FreeBSDオンラインマニュアル(man) FreeBSD time(1)
>> Linuxオンラインマニュアル(man) Linux time(7)
>> Linuxオンラインマニュアル(man) Linux time(2)
>> Linuxオンラインマニュアル(man) Linux time(1)