今回は速度計測ネタです。いわゆるベンチマークというやつです。ベンチマークテストにはDhrystone(ドライストーン)などの有名なものもありますが、UNIXコマンドにはtimeという便利なものがあります。今回は、このコマンドを使ってみましょう。
今回もサンプルプログラムなどはデスクトップのsampleディレクトリに入れておくことにします。
使っているシェルを確認
timeコマンドは以後に指定されたプログラムの開始から終了までにかかった時間を計測し結果を出力してくれます。使い方は割と簡単です。
といきたいところですが、ここで注意事項があります。ここではtimeコマンドはzshではなくbashのシェル上で動かすことにします。また、/usr/bin/timeのtimeとは別です。要するに面倒な(?)ことに
bashの内部コマンド time
zshの内部コマンド time
/usr/bin/time
と3つあるわけです。それぞれ出力結果や使用できるオプションが異なります。最初にbashの内部コマンドのtimeを使うことにします。
macOSの場合はデフォルトではzshなのでターミナルでbashに切り替えてください。
バージョンは関係ないのでHomebrewでbash 4を入れている場合は、それを使ってください。macOSでbashに切り替えるには以下のようにbashと入力するだけです。
bash
UbuntuなどLinux系の場合は基本的にbashがデフォルトになっているので、そのままtimeコマンドを実行するだけです。もし、デフォルトのシェルがbashではない場合はmacOSと同様にbashと入力すれば切り替わります。
今使っているシェルがわからない場合は以下のようにコマンドを入力してください。
echo $0
ちなみに使えるシェルを確認するには以下のように入力します。
cat /etc/shells
timeコマンドのオプション
timeコマンドについてはman timeとすると説明がでてきます。ただし、表示されるのは/usr/bin/timeのものです。このため、bash, zshの内部コマンドのtimeでは使えないオプションもあります。例えば/usr/bin/timeでは-oで結果をファイルに出力できますが、bashのtimeコマンドでは使用できません。
timeコマンドで速度計測
少し長くなりましたがtimeコマンドを使って実行にかかった時間を計測してみましょう。まず、簡単なところでecho 123の速度を計測します。以下のようにコマンドを入力します。
time echo 123
実行するとかかった時間が表示されます。realはコマンド実行にかかった時間、userはユーザーCPU時間、sysはシステムCPU時間になります。
echoでは時間が短すぎるので、もう少し時間のかかるコマンドを実行してみましょう。sleep 3なら3秒時間がかかるはずなので、実行時間がどうなるかやってみます。1回ではなく3回実行した結果は以下の図のようになります。いろいろな関係できっかり3秒にはなりません。
time sleep 3
今度は時間のかかるfindコマンドを実行してみましょう。ユーザーディレクトリ以下から、なさそうなファイルの拡張子を指定してみます。
time find ~/ -name *.mzt
ファイルが多いとそれなりに時間がかかりますが、ファイルがほぼない場合はすぐに終わります。また、検索対象デバイスがハードディスクなのかSSDなのかによっても異なります。
という事で、今度は同じファイルを外付けSSDと内部のSSDと、SDカードからコピーして時間を比較してみましょう。
コピーはcpコマンドを使います。それぞれ計測した結果は以下のようになります。SDカードやSSDのファイルパスは環境によって異なるので、以下のコマンドを使って計測したい場合は環境に合わせて変更してください。
・内蔵SSDから内蔵SSD
time cp 0.MTS 1.MTS
・外付けSSDから内蔵SSD
time cp /Volumes/photoMax15/0.MTS ~/Desktop/Sample/0.MTS
・SDカードから内蔵SSD
time cp /Volumes/CAM_SD/0.MTS ~/Desktop/sample/0.MTS
自作のシェルスクリプトの処理速度を計測
timeコマンドの便利なところは自作のシェルスクリプトの速度も計測できる点です。
まず、簡単なところで繰り返し処理を計測してみましょう。bashの繰り返しはforですが、いくつか書き方があります。そこで、書き方によって、どのくらい速度が異なるのかを計測してみます。基本的に処理速度のネックとなるのは繰り返し部分です。
なお、以下で実行するシェルスクリプトは0から999まで画面に数値を表示するだけのものです。