Seasons.NET

ちょっとした技術ブログです

preインクリメントとpostインクリメントのコストの違い

foreachを速くする方法はないかなぁ〜と調べていたんですが、
どうしてもvectoriteratorで回したものより全然速くて、
実際には、
C2D 2.2GHz vector v(要素:30000);
post++でイテレータを回した時:0.098
foreach:0.019

こりゃかなわんな〜ってことで
いろいろ調べていたら、post++にするか,pre++にするかで
圧倒的に速度が違うことを知った。
vc9.0のvectorの実装は、こうなっている

_Mytype& operator++()
{   // preincrement
    _Inc();
    return(*this);
}
_Mytype operator++(int)
{   // postincrement
    _Mytype _Tmp = *this;
    ++*this;
    return(_Tmp);
}

なんとまぁ、postインクリメントは、一時オブジェクトつくってるやーん!!!
こりゃコストかかるわけですわ・・・

んでpre++にしたら、0.009。
foreachの半分ですね。

ちなみにforeachは、内部実装が
Conditional Love: FOREACH Redux
になっていて、any_castしている分だけコストがかかります。
でも結構な速度をたたき出していると思います。


【補足】
前置と後置の場合では、左辺のことを考えるとなぜ、そのように一時オブジェクトが必要が
わかってきます。

Hoge h;
vector<Hoge>::iterator it = h.begin();
vector<Hoge>::iterator it2 = it++;

この場合、it2には、it+1される前のイテレーターが入っていなければいけないので
 +1する前に一時オブジェクトを生成してあげることが必要です。
前置の場合は、既に+1された値が左辺にはいる為、一時オブジェクトが必要じゃないってことです。