プロファイラ

プロファイラは、
実行時そのコードを何回通るかを示し、
高速化のヒントとなるものだが、
最近はそのコードにかかる秒数までも出してくれる。


http://www.compuware.co.jp/products/devpartner_fm/dpsprofiler.html


しかし、これには罠があり、
数値を鵜呑みにせずうまく使う必要がある。


例によって1000万回回すコードを書く。


// map版
map m;
for(int i = 0; i < n; i++)
m.insert(make_pair(i, a[i]));

int sum = 0;
for(int i = 0; i < 10000000; i++) {
map::const_iterator p
= m.find(i % n);
sum += p->second;
}


// vector
vector v;
for(int i = 0; i < n; i++)
v.push_back(a[i]);

int sum = 0;
for(int i = 0; i < 10000000; i++) {
sum += v[i % n];
}


// rand版
int sum = 0;
for(int i = 0; i < 10000000; i++) {
sum += rand() % n;
}


// sin版
double sum = 0;
for(int i = 0; i < 10000000; i++) {
sum += sin)((double)(i % n))(;
}

これらを、
Debugモード(最適化無し)、
Releaseモード(/O2)、
プロファイラ(Debugモード、最適化無し)、
で実行時間を比較した。
(プロファイラは、出力の数字)

コード Debug Release Profiler
map 35.28 0.61 9.91
vector 8.63 0.03 3.29
rand 0.16 0.15 8.74
sin 1.13 0.81 10.24

単位は秒

DebugとReleaseの違いはおいといて、
比較すべきはProfilerとReleaseである。
もっと分かりやすく比を取ってみよう。

コード Profiler/Release
map 16.2
vector 110
rand 58.3
sin 12.4

プログラム全体で、STLが実行速度の足を引っ張っているとする。
中でもmapのfindとvectorの値の参照がよく使われているとする。
その中でもvectorの値の参照にかかる時間が非常に大きいとする。
しかし、ここで分かることは、
プロファイラで、例えば、
vectorの値の参照が70%で、
mapのfindが30%の時間がかかったという数字が出たとしても、
プロファイラを外して最適化をかけると、
vectorの方が相対的に7倍速くなるから、
vectorの値の参照が25%、
mapのfindが75%になるということである。
だから、プロファイラでmapを使ったら速くなった、
といってもよく試して採用しないといけない。


ちなみに、このコンパイラは先日と違うものである。