i++と++iだとテンポラリオブジェクトを作る必要が無い分++iの方が効率がいいというのはMore Effective C++を読んで知っていたのですが、実際のところどの程度違いが出るのか知らなかったので実験してみました。
1073741824回forループさせてi++と++iでそれぞれインクリメントした場合でどのくらい処理時間に違いが出るかという実験です。30回計測した平均を比較するのを10回やりました。
実験環境は以下の通りです。
Compiler: Visual C++ 2010 64tit
OS: Windows 7 64bit
CPU: Intel core-i7 860 2.8GHz
Memory: 8GB
Releaseモードでコンパイラによる最適化なしで実験を行いました。
以下が結果です。
1073741824回forループさせてi++と++iでそれぞれインクリメントした場合でどのくらい処理時間に違いが出るかという実験です。30回計測した平均を比較するのを10回やりました。
実験環境は以下の通りです。
Compiler: Visual C++ 2010 64tit
OS: Windows 7 64bit
CPU: Intel core-i7 860 2.8GHz
Memory: 8GB
Releaseモードでコンパイラによる最適化なしで実験を行いました。
以下が結果です。
i++: 2.323300, ++i: 2.315500 -> ++i
i++: 2.342633, ++i: 2.329867 -> ++i
i++: 2.335500, ++i: 2.335767 -> i++
i++: 2.330267, ++i: 2.331167 -> i++
i++: 2.326967, ++i: 2.331334 -> i++
i++: 2.327000, ++i: 2.322900 -> ++i
i++: 2.336100, ++i: 2.329500 -> ++i
i++: 2.339967, ++i: 2.343800 -> i++
i++: 2.331100, ++i: 2.330200 -> ++i
i++: 2.330333, ++i: 2.329633 -> ++i
10回中6回が++iの方が速かったという微妙な結果に終わりました。誤差の範囲でしか違いが出なかったのは、きっとint型の変数を一回作って破棄する程度の処理は今のCPUではほぼ0秒なんでしょう。
ということで現在のマシンスペックであれば、どちらを使っても大して差は出ないという結論です。もちろん、コンパイラの自動最適化を使えば勝手にその辺は++iの方の処理に直してくれるとは思うのですが、本質的には++iの方が効率がいいということは変わらないはずなので、i++と++iのどちらでも良くて可読性が左右されないのであれば、++iを使うべきかと思います。
こういうことって学校では全く教えてくれなかった気がします。むしろ、i++で書くのが普通みたいな風に覚えさせられていたと思います。まぁ、処理時間に大きな差は出ないし、コンパイラが勝手に直してくれるからろくにプログラムを書けていない学生にそこまで細かい話は教える必要はないという風に教える側も思っていたのかもしれませんが、学校に在学中に全く説明してもらえる機会がなかったというのも残念なことです。下手したら一生知らないままですからね。
もし自分が教える側だったとしたら、ある程度書けるようになった人はこういう本質的なことはちゃんと理解しておくべきだとは思うので、そういう人たち向けに説明してあげたいと思います。
ちなみに以下が実験で使用したコードです。時間計測には個人ライブラリ(wsp::)を使っています。
10回中6回が++iの方が速かったという微妙な結果に終わりました。誤差の範囲でしか違いが出なかったのは、きっとint型の変数を一回作って破棄する程度の処理は今のCPUではほぼ0秒なんでしょう。
ということで現在のマシンスペックであれば、どちらを使っても大して差は出ないという結論です。もちろん、コンパイラの自動最適化を使えば勝手にその辺は++iの方の処理に直してくれるとは思うのですが、本質的には++iの方が効率がいいということは変わらないはずなので、i++と++iのどちらでも良くて可読性が左右されないのであれば、++iを使うべきかと思います。
こういうことって学校では全く教えてくれなかった気がします。むしろ、i++で書くのが普通みたいな風に覚えさせられていたと思います。まぁ、処理時間に大きな差は出ないし、コンパイラが勝手に直してくれるからろくにプログラムを書けていない学生にそこまで細かい話は教える必要はないという風に教える側も思っていたのかもしれませんが、学校に在学中に全く説明してもらえる機会がなかったというのも残念なことです。下手したら一生知らないままですからね。
もし自分が教える側だったとしたら、ある程度書けるようになった人はこういう本質的なことはちゃんと理解しておくべきだとは思うので、そういう人たち向けに説明してあげたいと思います。
ちなみに以下が実験で使用したコードです。時間計測には個人ライブラリ(wsp::)を使っています。
#include <stdio.h>
#include <wsp/core/fn-util.h>
void IncrementTest(){
int n = 1<<30;
int i, j;
int num_test = 30;
float time_ipp = 0.0;
float time_ppi = 0.0;
for(j=1; j<=num_test; j++){
i=0;
wsp::StartTimer();
for(; i!=n; i++){}
time_ipp += wsp::StopTimer();
i=0;
wsp::StartTimer();
for(; i!=n; ++i){}
time_ppi += wsp::StopTimer();
}
printf("i++: %f\n", time_ipp/num_test);
printf("++i: %f\n", time_ppi/num_test);
}
void main(){
for(int i=0; i<10; ++i){
IncrementTest();
}
}