C++での記述 if (i++ < 10) Hoge(i) 生成されるアセンブラ mov ebx, eax inc eax cmp ebx, 10 jnc L1 push eax call Hoge L1:
C++での記述 if (++i < 11) Hoge(i); 生成されるアセンブラ inc eax cmp eax, 11 jnc L1 push eax call Hoge L1:
※実際には、この程度のコードならほとんどのコンパイラは最適化が可能なので、実行時の差異は生じません。
※生成されるアセンブラはイメージです。実際にはコンパイラによって生成されるコードは異なります。
C++での記述
CFoo foo;
if (foo++ < 10) Hoge(foo)
インライン展開されるコード
CFoo tmp = foo;
foo.m_value.plus1();
if (CFoo::operator < (tmp.m_value, 10))
{
Hoge(foo)
}
C++での記述
CFoo foo;
if (++foo < 11) Hoge(foo);
インライン展開されるコード
if (CFoo::operator < (foo.m_value.plus1() , 11))
{
Hoge(foo)
}
CFooの実装は以下のようになる。
struct CValue {
CValue & plus1();
}
bool operator < (const CValue&, int);
struct CFoo {
CValue m_value;
CFoo() {}
bool operator < (int n) { return m_value < n; }
CFoo& operator ++() {
m_value .plus1();
return *this;
}
CFoo operator ++(int) {
CFoo tmp = *this; //<- オブジェクトの生成とコピーが発生
m_value .plus1();
return tmp; //<- オブジェクトの生成とコピーが発生
}
}
STLのvector<int>とmap<int,int>のiteratorをインクリメント(++)する実行時間を、前置きと後置きで比較してみました。
| オブジェクト | map<> iterator++ | map<> ++iterator | vector<> iterator++ | vector<> ++iterator |
| 実行時間(Releaseビルド) | 1.300815 | 0.300459 | 0.567246 | 0.566541 |
| 比率 | 100.00% | 23.10% | 100.00% | 99.98% |
| 実行時間(Debugビルド) | 1.361722 | 0.108110 | 1.203101 | 0.157290 |
| 比率 | 100.0% | 7.94% | 100.00% | 13.07% |
この結果を見ても、意味のない i++ を書きますか?
※測定環境 Athlon64 3.0GHz x2 VisualStudio 2009