C++ C++;构造函数与初始化列表速度比较

C++ C++;构造函数与初始化列表速度比较,c++,constructor,initialization-list,C++,Constructor,Initialization List,构造函数和初始化列表之间的执行时间是否有任何差异?(或者只是编码偏好的问题)。 我有一组需要频繁创建的对象,我想知道使用初始化列表而不是构造函数是否会提高性能 如果我要创建一百万个a类实例和一百万个B类实例,那么哪个选择更好(对象表示网络中生成的数据包,因此这些数字) 如果基元类型的任何一个构造函数都比另一个快(如示例中所示),那么用类型替换a和b会更快吗 类型示例: class AType { private: string a, b; public: AT

构造函数和初始化列表之间的执行时间是否有任何差异?(或者只是编码偏好的问题)。 我有一组需要频繁创建的对象,我想知道使用初始化列表而不是构造函数是否会提高性能

如果我要创建一百万个a类实例和一百万个B类实例,那么哪个选择更好(对象表示网络中生成的数据包,因此这些数字)

如果基元类型的任何一个构造函数都比另一个快(如示例中所示),那么用类型替换a和b会更快吗

类型示例:

 class AType {
   private:
     string a, b;

   public:
     AType(string a_var, string b_var):a(a_var), b(b_var) {}; 
};

如果成员的类型或多或少比较复杂,那么赋值初始化将首先导致默认构造函数调用,然后是
运算符=
,这可能需要更长的时间。

如果类型是内置/固有类型,则性能不会得到改善

也就是说:

:在所有其他条件相同的情况下,如果 您使用初始化列表而不是赋值


不同之处在于没有普通默认构造函数的类型,它是由类
B
中的编译器为您调用的。您的班级
B
相当于:

 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;
     }
  };
若不将成员变量或基类构造函数放入初始化列表中,则会为它们调用默认构造函数
int
是基本类型-它的默认构造函数不需要任何成本-所以在您的示例中没有区别,但是对于更复杂的类型,构造函数+赋值的成本可能不仅仅是构造

一些有趣的例子,只是为了说明区别:

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;
     }
};

在构造函数中使用初始化列表而不是赋值是普遍接受的做法,这有一个很好的理由

初始化列表可用于初始化POD(普通旧数据)和用户定义的类型。初始化POD类型时,效果与赋值运算符完全相同,这意味着POD类型的初始化列表或构造函数中的赋值之间没有性能差异

当我们考虑非POD类型时,事情会变得更有趣。在调用构造函数之前,先调用父类的构造函数,然后调用任何包含的成员,默认情况下调用无参数构造函数。使用初始化列表,您可以选择调用哪个构造函数


所以要回答这个问题,有一个性能差异,但仅在初始化非POD类型时。

初始化列表是有益的引用类型、成员类对象或常量成员。否则需要更多的时间

查看我的测试代码:

#include <iostream>
#include <ctime>

using namespace std;

class A{
    int a;
public:
    A(int a_):a(a_){}
};

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

    B(int b_){
        b=b_;
    }
};

class C{
    B b;
public:
    C(int c_):b(c_){
    }
};

class D{
    B b;
public:
    D(int d_){
        b=d_;
    }
};

int main()
{
    clock_t start1[10], start2[10], end1[10], end2[10];
    for(int j=0;j<10;j++){
        start1[j]=clock();
        for(int i=0;i<100000;i++){   
            A *newA=new A(i);
            delete newA;
        }
        end1[j]=clock();
        start2[j]=clock();
        for(int i=0;i<100000;i++){   
            B *newB=new B(i);
            delete newB;
        }
        end2[j]=clock();
    }
    double avg1=0, avg2=0;
    for(int i=0;i<10;i++){
        avg1+=(end1[i]-start1[i]);
        avg2+=(end2[i]-start2[i]);
    }
    cout << avg1/avg2 << endl;

    for(int j=0;j<10;j++){
        start1[j]=clock();
        for(int i=0;i<100000;i++){   
            C *newC=new C(i);
            delete newC;
        }
        end1[j]=clock();
        start2[j]=clock();
        for(int i=0;i<100000;i++){   
            D *newD=new D(i);
            delete newD;
        }
        end2[j]=clock();
    }
    avg1=avg2=0;
    for(int i=0;i<10;i++){
        avg1+=(end1[i]-start1[i]);
        avg2+=(end2[i]-start2[i]);
    }
    cout << avg1/avg2 << endl;

    system("pause");
    return 0;
}
#包括
#包括
使用名称空间std;
甲级{
INTA;
公众:
A(inta_uu):A(A_u){
};
B类{
int b;
公众:
B(){
}
B(int B){
b=b_u2;;
}
};
C类{
B B;
公众:
C(内部C):b(内部C){
}
};
D类{
B B;
公众:
D(内部数据){
b=d_2;;
}
};
int main()
{
时钟开始1[10]、开始2[10]、结束1[10]、结束2[10];

对于(int j=0;为什么你问我们?没有线索你正在使用什么编译器。只是测量它。希望有人知道答案。我也想知道是好的实践还是不可以的,用初始化列表设置变量值。这是更好的解决方案。在C++中,初始化变量总是更好的。实际上,它不会像<代码> < /Cord>。
b
int
s。仅适用于非POD类型。如果成员是示例中的简单int,则没有区别。类型将如何影响执行速度?我不确定“替换为类型”是什么意思。我将其解释为被更复杂的类型所取代。如果a和b被objectsHmm所取代,则在构造函数中进行休眠,这就解释了延迟。但是如果我们只进行赋值呢(意味着a和b为对象,且仅在a类和B@Sebi你是说
a
b
不是
a
b
的成员吗?是的,我指的是a和b是类型,在传递给它们之前已经实例化了contructors@Sebi我不确定我是否理解。你可以吗使用新的示例更新问题?@Sebi,我不确定我是否完全理解您的意思,但是除了类型之外,没有其他方法可以阻止编译器在构造函数体开始之前调用数据成员的默认构造函数,除非使用成员初始值设定项。
#include <iostream>
#include <ctime>

using namespace std;

class A{
    int a;
public:
    A(int a_):a(a_){}
};

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

    B(int b_){
        b=b_;
    }
};

class C{
    B b;
public:
    C(int c_):b(c_){
    }
};

class D{
    B b;
public:
    D(int d_){
        b=d_;
    }
};

int main()
{
    clock_t start1[10], start2[10], end1[10], end2[10];
    for(int j=0;j<10;j++){
        start1[j]=clock();
        for(int i=0;i<100000;i++){   
            A *newA=new A(i);
            delete newA;
        }
        end1[j]=clock();
        start2[j]=clock();
        for(int i=0;i<100000;i++){   
            B *newB=new B(i);
            delete newB;
        }
        end2[j]=clock();
    }
    double avg1=0, avg2=0;
    for(int i=0;i<10;i++){
        avg1+=(end1[i]-start1[i]);
        avg2+=(end2[i]-start2[i]);
    }
    cout << avg1/avg2 << endl;

    for(int j=0;j<10;j++){
        start1[j]=clock();
        for(int i=0;i<100000;i++){   
            C *newC=new C(i);
            delete newC;
        }
        end1[j]=clock();
        start2[j]=clock();
        for(int i=0;i<100000;i++){   
            D *newD=new D(i);
            delete newD;
        }
        end2[j]=clock();
    }
    avg1=avg2=0;
    for(int i=0;i<10;i++){
        avg1+=(end1[i]-start1[i]);
        avg2+=(end2[i]-start2[i]);
    }
    cout << avg1/avg2 << endl;

    system("pause");
    return 0;
}