优化答案(g++ -O2
):
您没有使用最终结果,因此编译器可以自由地优化整个循环。
这就是发生在array case https://gcc.godbolt.org/z/eLBTXI.
main:
xor eax, eax
ret
But the vector
分配和释放堆内存,这使优化变得复杂,并且编译器倾向于谨慎行事将其留在原处 https://gcc.godbolt.org/z/urlnh9:
main:
xor eax, eax
ret
_GLOBAL__sub_I_v:
sub rsp, 8
mov edi, 400000000
mov QWORD PTR v[rip], 0
mov QWORD PTR v[rip+8], 0
mov QWORD PTR v[rip+16], 0
call operator new(unsigned long)
lea rdx, [rax+400000000]
mov QWORD PTR v[rip], rax
mov QWORD PTR v[rip+16], rdx
.L6:
mov DWORD PTR [rax], 0
add rax, 4
cmp rdx, rax
jne .L6
mov QWORD PTR v[rip+8], rdx
mov esi, OFFSET FLAT:v
mov edx, OFFSET FLAT:__dso_handle
mov edi, OFFSET FLAT:_ZNSt6vectorIiSaIiEED1Ev
add rsp, 8
jmp __cxa_atexit
所以这就是为什么array
在这种特殊情况下,版本更快。在更现实的应用程序中,差异不会那么显着,并且主要取决于堆分配/释放时间vector
case.
优化关闭的答案(g++
):
不要对未经优化的编译内容进行基准测试。
差异可能是由于vector
迭代器未内联。因此,与数组访问相比,在调试中访问向量元素会更多地产生额外的间接寻址。