После анализа сборки, сгенерированной VC ++ для этих двух случаев, вот что я нашел. Компилятор встроил практически все и генерировал очень похожие циклы для инициализации после выделения памяти. В случае вектора внутренний цикл выглядит так:
013E3FC0 test eax,eax
013E3FC2 je std::_Uninit_def_fill_n<vec2 *,unsigned int,vec2,std::allocator<vec2>,vec2>+19h (13E3FC9h)
013E3FC4 mov dword ptr [eax],edx
013E3FC6 mov dword ptr [eax+4],esi
013E3FC9 add eax,8
013E3FCC dec ecx
013E3FCD jne std::_Uninit_def_fill_n<vec2 *,unsigned int,vec2,std::allocator<vec2>,vec2>+10h (13E3FC0h)
где регистры edx
и esi
были обнулены вне цикла:
00013FB5 xor edx,edx
00013FB7 xor esi,esi
00013FB9 lea esp,[esp]
В случае new[]
внутренний цикл выглядит следующим образом:
009F1800 mov dword ptr [ecx],0
009F1806 mov dword ptr [ecx+4],0
009F180D add ecx,8
009F1810 dec edx
009F1811 jns main+30h (9F1800h)
Различия очень незначительны, еще несколько инструкций в случае vector
, но, вероятно, также быстрее mov
s из регистров. Поскольку в большинстве реальных случаев конструкторы делают гораздо больше, чем присваивают нули, эта разница вряд ли может быть вообще заметна. Так что ценность этого тестирования сомнительна.