シェルスクリプトで実行しているプログラムがいくつかあります。
./myprogram1
./myprogram2
...
ソースコードを編集して個々のプログラムをプロファイリングできることはわかっていますが、スクリプト自体をプロファイリングすることによって実行された合計時間を測定できる方法があるかどうかを知りたいと思いました。この目的に使用できるタイマープログラムはありますか?もしそうなら、その測定はどのくらい正確ですか?
シェルスクリプトで実行しているプログラムがいくつかあります。
./myprogram1
./myprogram2
...
ソースコードを編集して個々のプログラムをプロファイリングできることはわかっていますが、スクリプト自体をプロファイリングすることによって実行された合計時間を測定できる方法があるかどうかを知りたいと思いました。この目的に使用できるタイマープログラムはありますか?もしそうなら、その測定はどのくらい正確ですか?
回答:
Jon Linの提案に従って時間を使用することから始めます。
$ time ls test
test
real 0m0.004s
user 0m0.002s
sys 0m0.002s
スクリプトがどのUNIXで実行されているかは言いませんが、Linuxではstrace、Solaris / AIXではtrussです。hp-uxのtuscを使用すると、プロセスの動作について多くのことを学べると思います。私はstraceの-cオプションがいい要約を得るのが好きです:
]$ strace -c ls
test
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
89.19 0.000998 998 1 execve
10.81 0.000121 121 1 write
0.00 0.000000 0 12 read
0.00 0.000000 0 93 79 open
0.00 0.000000 0 16 close
0.00 0.000000 0 2 1 access
0.00 0.000000 0 3 brk
0.00 0.000000 0 2 ioctl
0.00 0.000000 0 4 munmap
0.00 0.000000 0 1 uname
0.00 0.000000 0 6 mprotect
0.00 0.000000 0 2 rt_sigaction
0.00 0.000000 0 1 rt_sigprocmask
0.00 0.000000 0 1 getrlimit
0.00 0.000000 0 30 mmap2
0.00 0.000000 0 8 7 stat64
0.00 0.000000 0 13 fstat64
0.00 0.000000 0 2 getdents64
0.00 0.000000 0 1 fcntl64
0.00 0.000000 0 1 futex
0.00 0.000000 0 1 set_thread_area
0.00 0.000000 0 1 set_tid_address
0.00 0.000000 0 1 set_robust_list
0.00 0.000000 0 1 socket
0.00 0.000000 0 1 1 connect
------ ----------- ----------- --------- --------- ----------------
100.00 0.001119 205 88 total
これらのトレースタイプのプログラムをアタッチすると、プログラムの速度が多少低下する可能性があることにも注意してください。
正確なプロファイリングではありませんが、実行中にスクリプトを追跡できます。set -xv
追跡するセクションの前とセクションのset +xv
後に置きます。set -x
xtraceを有効にします。これにより、実行されるすべての行が表示されます。set -v
冗長モードを有効にします。これにより、変数の割り当てなど、効果があるが実行されない行も表示されます。
トレースにタイムスタンプを付けることもできます。すべての行にタイムスタンプを付けることができる端末エミュレータが必要です。私が知っているのはWindowsプログラムであるRealTermだけですが、Wineで動作します。grabserial
実際のシリアルポート以外では試していませんが、も使用できる場合があります。シェルを実行ps -p $$
すると、使用man
しているシリアルデバイスを確認できます(使用しない場合は、TTY列をps
出力に含める方法を確認するために使用します)。
また、Stack Overflowのシェルスクリプトのパフォーマンスプロファイリングツールもご覧ください。
time
数回の繰り返し同じコマンドを複数回実行することによるプロファイリング
time (for ((n=0;n<10;n++)); do echo "scale=1000; 4*a(1)" | bc -l; done)
はecho "scale=1000; 4*a(1)" | bc -l
piを計算time (...)
し、for
ループが単一のコマンドとして実行されるようにします。
私はここで少なくとも2回ここにいるので、私は解決策を実装しました:
https://github.com/walles/shellprof
スクリプトを実行し、印刷されたすべての行を透過的に計時し、最後に、画面に最も長く表示された行のトップ10リストを印刷します。
~/s/shellprof (master|✔) $ ./shellprof ./testcase.sh
quick
slow
quick
Timings for printed lines:
1.01s: slow
0.00s: <<<PROGRAM START>>>
0.00s: quick
0.00s: quick
~/s/shellprof (master|✔) $