今日はプロファイルについて書きたいと思います。プロファイルとは、プログラムの中の個々の関数がどれくらい呼び出されているか、そしてどれくらい時間を消費しているかの統計を調べることを言います。具体的には、Cでコンパイルするときに、-pgオプションをつけてコンパイルをします。その後gprofプログラムにより、プロファイルを表示することができます。
$ gcc -pg demo.c subgroup.c subset.c list.c cayley.c permutation.c
$ gprof ./a.out gmon.out
例えば次のサンプルは、対称群(置換群)の部分群を求めるプログラムをプロファイルしたものです。このプロファイルからは、is_set0とq_sortにおいて多くの時間が割かれていることがわかります。従って、プログラムの速度を上げるには、この2つの関数を改良することが効果的です。実際にq_sorをCの標準ライブラリのqsortに代え、is_set0(これはセットであるかどうかのチェックをする関数)をノーチェック、つまり常にセットが正常だという返り値を戻すようにしたところ、60秒かかっていたものが14秒に短縮されました。
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
44.64 25.84 25.84 381729969 0.00 0.00 is_set0
40.11 49.05 23.21 29581 0.00 0.00 q_sort
4.27 51.52 2.47 190741601 0.00 0.00 set_cmp
2.66 53.05 1.54 59320 0.00 0.00 l_lookup_with_cmp
2.28 54.38 1.32 381761640 0.00 0.00 fact
2.27 55.69 1.31 381670649 0.00 0.00 is_set
1.02 56.28 0.59 23761 0.00 0.00 l_lookup
0.92 56.81 0.53 14032 0.00 0.00 l_append
0.76 57.25 0.44 29581 0.00 0.00 uniq
0.59 57.59 0.34 29581 0.00 0.00 set_mul_ss
… … … … … … … … … …
… … … … … … … … … …
このようにプロファイルを調べることは実行速度を上げるためには便利です。また、is_set0のようなチェック機能は、堅いプログラム(バグの少ないプログラム、ロブストともいう)では必要ですが、一旦動くことが確認できれば、チェックをはずすことも速度向上につながります。