Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Constructors vs Initialization Lists speed comparison

Are there any differences in execution time between constructors and initialization lists?(or is it just a matter of coding preference). I have a set of objects that needs to be created frequently and would like to know if there is any performance gain by using initialization lists instead of constructors.

If I were to create a million instances of class A and another million of class B which choice would be better(the objects represent packets generated within a network hence these numbers).

 class A {
   private:
     int a, b;

   public:
     A(int a_var, int b_var):a(a_var), b(b_var) {}; 
 };

 class B {
   private:
     int a, b;

   public:
     B(int a_var, int b_var) {
        a = a_var;
        b = b_var;
     }
};

If any of the constructors is faster than the other for primitive types(as in the example) will it be faster if a and b were to be replaced by types?

Type example:

 class AType {
   private:
     string a, b;

   public:
     AType(string a_var, string b_var):a(a_var), b(b_var) {}; 
};
like image 248
Sebi Avatar asked Nov 03 '12 22:11

Sebi


People also ask

Is initialization list faster?

Conclusion: All other things being equal, your code will run faster if you use initialization lists rather than assignment.

Should my constructors use initialization lists or assignment?

Should my constructors use “initialization lists” or “assignment”? ¶ Δ Initialization lists. In fact, constructors should initialize as a rule all member objects in the initialization list.

Why use member initialization lists?

Initialization lists allow you to choose which constructor is called and what arguments that constructor receives. If you have a reference or a const field, or if one of the classes used does not have a default constructor, you must use an initialization list.

What is the advantage of initializer list in C++?

The most common benefit of doing this is improved performance. If the expression whatever is the same type as member variable x_, the result of the whatever expression is constructed directly inside x_ — the compiler does not make a separate copy of the object.


2 Answers

The difference is for types with no trivial default constructor, which is called for you by compiler in your class B. Your class B is equivalent to:

 class B {
   private:
     SleepyInt a, b;

   public:
     // takes at least 20s
     B(int a_var, int b_var) : a(), b()
     //                      ^^^^^^^^^^ 
     {
        a = a_var;
        b = b_var;
     }
  };

If you do not place member variable or base class constructor in initialization list - ithe default constructor is called for them. int is basic type - its default constructor costs nothing - so no difference in your example, but for more complex types constructor+assignment might cost more than just constructing.

Some funny example, just to illustrate the difference:

class SleepyInt {
public:
  SleepyInt () { 
    std::this_thread::sleep_for(std::chrono::milliseconds( 10000 ));  
  }
  SleepyInt (int i) {}
  SleepyInt & operator = (int i) { return *this; }
};

class A {
   private:
     SleepyInt a, b;

   public:
     A(int a_var, int b_var):a(a_var), b(b_var) {}; 
 };

 class B {
   private:
     SleepyInt a, b;

   public:
     // takes at least 20s
     B(int a_var, int b_var) {
        a = a_var;
        b = b_var;
     }
};
like image 106
PiotrNycz Avatar answered Sep 20 '22 04:09

PiotrNycz


It is commonly accepted practice to use initialization lists as opposed to assignment in a constructor, and there's a very good reason for that.

Initialization lists can be used to initialize both POD (Plain Old Data) and user-defined types. When initializing a POD type, the effect is exactly the same as an assignment operator, meaning there is no performance difference between initialization lists or assignment in a constructor for POD types.

When we consider non-POD types things get more interesting. Before the constructor is called, constructors for the parent class and then any contained members are invoked, and by default the no-argument constructor is called. Using an initialization list you are able to choose which constructor is called.

So to answer the question, there is a performance difference, but only when initializing non-POD types.

like image 29
blockchaindev Avatar answered Sep 22 '22 04:09

blockchaindev