c++performancemember-initializationctor-initializer

Would a member initializer, or assignment in the constructor initialize a member faster?


class A {
   public:
   int a;
   A(int x)
   {
      a = x;
   }
};

OR

class B {
       public:
       int b;
       B(int x):b(x){}
};

Which one would initialize the object faster ? Or will same code be generated ultimately for both and the time taken to initialize will remain the same ? Or does it depend on the compiler ?


Solution

  • For POD members, including int, they will be the same, because the member won't be constructed twice.

    For types with a default constructor, the second will be faster, because the first option is equivalent to:

    A(B x) : a()
    {
       a = x;
    }
    

    if a is a member of type B (with a default constructor).

    Note that there are situations where you must use initializer lists: const members, reference members, members of a class-type that don't have a default constructor.

    POD-member:

    No initializer list:

       A(int x)
    001F1430  push        ebp  
    001F1431  mov         ebp,esp  
    001F1433  sub         esp,0CCh  
    001F1439  push        ebx  
    001F143A  push        esi  
    001F143B  push        edi  
    001F143C  push        ecx  
    001F143D  lea         edi,[ebp-0CCh]  
    001F1443  mov         ecx,33h  
    001F1448  mov         eax,0CCCCCCCCh  
    001F144D  rep stos    dword ptr es:[edi]  
    001F144F  pop         ecx  
    001F1450  mov         dword ptr [ebp-8],ecx  
       {
          a = x;
    001F1453  mov         eax,dword ptr [this]  
    001F1456  mov         ecx,dword ptr [x]  
    001F1459  mov         dword ptr [eax],ecx  
       }
    

    Initializer list:

       A(int x) : a(x)
    00E71430  push        ebp  
    00E71431  mov         ebp,esp  
    00E71433  sub         esp,0CCh  
    00E71439  push        ebx  
    00E7143A  push        esi  
    00E7143B  push        edi  
    00E7143C  push        ecx  
    00E7143D  lea         edi,[ebp-0CCh]  
    00E71443  mov         ecx,33h  
    00E71448  mov         eax,0CCCCCCCCh  
    00E7144D  rep stos    dword ptr es:[edi]  
    00E7144F  pop         ecx  
    00E71450  mov         dword ptr [ebp-8],ecx  
    00E71453  mov         eax,dword ptr [this]  
    00E71456  mov         ecx,dword ptr [x]  
    00E71459  mov         dword ptr [eax],ecx  
    

    i.e. identical, & that's because a isn't initialized before entry to the constructor body.

    Non-POD member:

    No initializer list:

    00EB1A80  push        ebp  
    00EB1A81  mov         ebp,esp  
    00EB1A83  sub         esp,0CCh  
    00EB1A89  push        ebx  
    00EB1A8A  push        esi  
    00EB1A8B  push        edi  
    00EB1A8C  push        ecx  
    00EB1A8D  lea         edi,[ebp-0CCh]  
    00EB1A93  mov         ecx,33h  
    00EB1A98  mov         eax,0CCCCCCCCh  
    00EB1A9D  rep stos    dword ptr es:[edi]  
    00EB1A9F  pop         ecx  
    00EB1AA0  mov         dword ptr [ebp-8],ecx  
    00EB1AA3  mov         ecx,dword ptr [this]  
    00EB1AA6  call        B::B (0EB11D6h)  
       {
           a = b;
       }
    00EB1AAB  mov         eax,dword ptr [this]  
    00EB1AAE  pop         edi  
    00EB1AAF  pop         esi  
    00EB1AB0  pop         ebx  
    00EB1AB1  add         esp,0CCh  
    00EB1AB7  cmp         ebp,esp  
    00EB1AB9  call        @ILT+315(__RTC_CheckEsp) (0EB1140h)  
    00EB1ABE  mov         esp,ebp  
    00EB1AC0  pop         ebp  
    00EB1AC1  ret         4  
    

    Initializer List:

    A(B b) : a(b)
       {
    00841650  push        ebp  
    00841651  mov         ebp,esp  
    00841653  sub         esp,0CCh  
    00841659  push        ebx  
    0084165A  push        esi  
    0084165B  push        edi  
    0084165C  push        ecx  
    0084165D  lea         edi,[ebp-0CCh]  
    00841663  mov         ecx,33h  
    00841668  mov         eax,0CCCCCCCCh  
    0084166D  rep stos    dword ptr es:[edi]  
    0084166F  pop         ecx  
    00841670  mov         dword ptr [ebp-8],ecx  
       }
    

    i.e. initializer list option is better.