GNU GCC の STL 実装 (バージョン 4.6.1)の特定のケースではstd::vector
、十分に高い最適化レベルでパフォーマンスの違いがあるとは思いません。
の前方イテレータの実装vector
は、 によって提供され__gnu_cxx::__normal_iterator<typename _Iterator, typename _Container>
ます。++
そのコンストラクタと後置演算子を見てみましょう:
explicit
__normal_iterator(const _Iterator& __i) : _M_current(__i) { }
__normal_iterator
operator++(int)
{ return __normal_iterator(_M_current++); }
そして、そのインスタンス化vector
:
typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;
ご覧のとおり、通常のポインターに対して後置インクリメントを内部的に実行し、独自のコンストラクターを介して元の値を渡し、それをローカル メンバーに保存します。このコードは、死んだ値の分析によって排除するのが簡単なはずです。
しかし、それは本当に最適化されていますか? 確認してみましょう。テストコード:
#include <vector>
void test_prefix(std::vector<int>::iterator &it)
{
++it;
}
void test_postfix(std::vector<int>::iterator &it)
{
it++;
}
出力アセンブリ (上-Os
):
.file "test.cpp"
.text
.globl _Z11test_prefixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE
.type _Z11test_prefixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE, @function
_Z11test_prefixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE:
.LFB442:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
movl 8(%ebp), %eax
addl $4, (%eax)
popl %ebp
.cfi_def_cfa 4, 4
.cfi_restore 5
ret
.cfi_endproc
.LFE442:
.size _Z11test_prefixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE, .-_Z11test_prefixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE
.globl _Z12test_postfixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE
.type _Z12test_postfixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE, @function
_Z12test_postfixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE:
.LFB443:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
movl 8(%ebp), %eax
addl $4, (%eax)
popl %ebp
.cfi_def_cfa 4, 4
.cfi_restore 5
ret
.cfi_endproc
.LFE443:
.size _Z12test_postfixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE, .-_Z12test_postfixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE
.ident "GCC: (Debian 4.6.0-10) 4.6.1 20110526 (prerelease)"
.section .note.GNU-stack,"",@progbits
ご覧のとおり、どちらの場合もまったく同じアセンブリが出力されます。
もちろん、カスタム イテレータやより複雑なデータ型の場合は、必ずしもそうであるとは限りません。ただし、vector
具体的には、プレフィックスとポストフィックス (ポストフィックスの戻り値をキャプチャしない) のパフォーマンスは同じであるようです。