異なるシェル間でスクリプトの実行時間を比較するために、一部のSEの回答は、次のようにbash
のbuilt-intime
コマンドを使用することを提案しています。
time bash -c 'foo.sh'
time dash -c 'foo.sh'
...etc、テストするすべてのシェル用。このようなベンチマークでは、各シェルの読み込みと初期化に必要な時間itselfを排除できません。たとえば、上記の両方のコマンドが 初期のフロッピーディスクの読み取り速度の遅いデバイス 、(124KB/s)、dash
(a 〜150K実行可能)は、約7xbash
(〜1M)よりも速くロードされ、シェルのロード時間はtime
の数値を歪めます-これらのシェルのプリロード時間は無関係です各シェルの下でのfoo.sh
の実行時間の測定afterシェルがロードされました。
within各シェルから実行できるスクリプトタイミングのために実行するのに最適なポータブルで一般的なユーティリティは何ですか?したがって、上記のコードは次のようになります。
bash -c 'general_timer_util foo.sh'
dash -c 'general_timer_util foo.sh'
注意:Shell built-intime
コマンドはありません。移植可能なものや一般的なものはないためです。
Utilがシェルの内部コマンドとパイプラインにかかる時間をベンチマークでき、ユーザーが最初にそれらをスクリプトにラップする必要がない場合はさらに良いでしょう。このような人工構文は役に立ちます:
general_timer_util "while read x ; do echo x ; done < foo"
一部のシェルのtime
はこれを管理できます。たとえば、bash -c "time while false ; do : ; done"
は機能します。システムで何が機能するか(そして機能しないか)を確認するには、次のことを試してください。
tail +2 /etc/shells |
while read s ; do
echo $s ; $s -c "time while false ; do : ; done" ; echo ----
done
time
はPOSIXによって指定される であり、POSIXが言及する唯一のオプションはAFAICT(-p
)はさまざまなシェルで正しくサポートされています:
$ bash -c 'time -p echo'
real 0.00
user 0.00
sys 0.00
$ dash -c 'time -p echo'
real 0.01
user 0.00
sys 0.00
$ busybox sh -c 'time -p echo'
real 0.00
user 0.00
sys 0.00
$ ksh -c 'time -p echo'
real 0.00
user 0.00
sys 0.00
高解像度タイマーをサポートする[〜#〜] gnu [〜#〜]date
コマンドを使用します。
START=$(date +%s.%N)
# do something #######################
"$@" &> /dev/null
#######################################
END=$(date +%s.%N)
DIFF=$( echo "scale=3; (${END} - ${START})*1000/1" | bc )
echo "${DIFF}"
そして、次のようにスクリプトを呼び出します。
/usr/local/bin/timing Dig +short unix.stackexchange.com
141.835
出力単位はミリ秒です。
time
ユーティリティは通常、シェルに組み込まれているため、「中立」タイマーとしては役に立たないようになっています。
ただし、このユーティリティは通常、外部ユーティリティ/usr/bin/time
としても利用でき、提案したタイミング実験を実行するために使用できます。
$ bash -c '/usr/bin/time foo.sh'
ここに解決策があります:
各シェルが自分自身をロードして初期化するのにかかる時間をなくす
各シェルからwithinから実行できます
シェル組み込みの
time
コマンドはありません。移植性や汎用性がないためです。
2つの部分があります。つまり、廃止予定ですが、_clock_gettime
_よりも移植性が高い gettimeofday
をラップする短いCプログラムと、そのプログラムを使用する短いシェルスクリプトです。スクリプトのソースの両側を読み取るマイクロ秒精度の時計を取得します。 Cプログラムは、タイムスタンプの1秒未満の精度を取得する唯一の移植可能な最小限のオーバーヘッドの方法です。
これがCプログラム_Epoch.c
_です。
_#include <sys/time.h>
#include <stdio.h>
int main(int argc, char **argv) {
struct timeval time;
gettimeofday(&time, NULL);
printf("%li.%06i", time.tv_sec, time.tv_usec);
}
_
そして、シェルスクリプトtimer
:
_#!/bin/echo Run this in the Shell you want to test
START=$(./Epoch)
. "$1"
END=$(./Epoch)
echo "$END - $START" | bc
_
これは標準の Shellコマンド言語 および bc
であり、POSIX互換シェルの下でスクリプトとして機能するはずです。
これは次のように使用できます。
_$ bash timer ./test.sh
.002052
$ dash timer ./test.sh
.000895
$ zsh timer ./test.sh
.000662
_
システム時間やユーザー時間は測定されず、単調でない壁時計の経過時間のみが測定されます。スクリプトの実行中にシステムクロックが変化すると、正しくない結果が得られます。システムに負荷がかかっている場合、結果は信頼できなくなります。シェル間で移植できるものは他にないと思います。
変更されたタイマースクリプトは、スクリプトの外でコマンドを実行する代わりに eval
を使用できます。
による入力のおかげで、大きな部分で/proc/uptime
およびdc
/bc
/awk
を使用して複数回改訂されたソリューションagc :
#!/bin/sh
read -r before _ < /proc/uptime
sleep 2s # do something...
read -r after _ < /proc/uptime
duration=$(dc -e "${after} ${before} - n")
# Alternative using bc:
# duration=$(echo "${after} - ${before}" | bc)
# Alternative using awk:
# duration=$(echo "${after} ${before}" | awk '{print $1 - $2}')
echo "It took $duration seconds."
/proc/uptime
が存在し、特定の形式を持っていることは明らかです。