让我们看看...
第一个循环:在std::vector对象上调用size成员函数N次operator[]和std::cout上N次operator<<。
第二个循环:在std::vector 对象上调用begin 和end 成员函数,在std::cout 上取消引用vector<int>::iterator 和N 次operator<<。
以下操作:size、operator[]、begin、end 和取消引用 vector<int>::iterator 具有恒定的复杂性。换句话说,没什么。 operator[] 可能会导致向基地址添加一些数字,并且向量迭代器很可能是原始指针。很明显,在标准输出上打印内容是这里的主导因素,这在两种情况下都是相同的。一般来说,没有理由相信其中一个会比另一个快。
只是为了好玩,我在笔记本电脑上尝试过,但我认为没有什么值得讨论的区别。
gdb 反汇编:gcc 4.8 (g++ -g -std=c++11 -O2 file.cc):
Dump of assembler code for function main():
5 {
0x0000000000400880 <+0>: push %r12
0x000000000040088d <+13>: push %rbp
0x000000000040088e <+14>: push %rbx
6 std::vector<int> myVec = { 1, 2, 3, 5, 6, 7 }; // some vector of ints
7
8 for (int i(0), j(myVec.size()); i < j; ++i) std::cout << myVec[i];
0x0000000000400887 <+7>: mov $0x6,%r12d
0x000000000040088f <+15>: xor %ebx,%ebx
0x00000000004008c0 <+64>: mov 0x0(%rbp,%rbx,4),%esi
0x00000000004008c4 <+68>: mov $0x601080,%edi
0x00000000004008c9 <+73>: callq 0x4007d0 <_ZNSolsEi@plt>
0x00000000004008ce <+78>: add $0x1,%rbx
0x00000000004008d2 <+82>: cmp %ebx,%r12d
0x00000000004008d5 <+85>: jg 0x4008c0 <main()+64>
9
10 std::cout << std::endl;
11
12 for (std::vector<int>::iterator it(myVec.begin()), j(myVec.end()); it != j; ++it) std::cout << *it;
0x00000000004008f0 <+112>: mov (%rbx),%esi
0x00000000004008f2 <+114>: mov $0x601080,%edi
0x00000000004008f7 <+119>: callq 0x4007d0 <_ZNSolsEi@plt>
0x00000000004008fc <+124>: add $0x4,%rbx
0x0000000000400900 <+128>: cmp %r12,%rbx
0x0000000000400903 <+131>: jne 0x4008f0 <main()+112>
13
14 std::cout << std::endl;
15 }
0x000000000040091c <+156>: pop %rbx
0x000000000040091d <+157>: pop %rbp
0x000000000040091e <+158>: xor %eax,%eax
0x0000000000400920 <+160>: pop %r12
0x0000000000400922 <+162>: retq