有关C++中trivial和non-trivial构造函数的问题【C和C++效率问题后续4】
众所周知,trivial比non-trivial构造函数在实例化一个类时速度要快许多。
对于下面这个类
class A
{
int i;
}
如果自己显式的定义一个构造函数那就成了non-trivial构造函数,那么在同样实例化一个A的对象时就会慢许多,(如:A a)。
现在想请问,它为什么会慢?也就是non-trivial比trivial构造函数多干了什么事情?
[解决办法]
我的理解, 建立一象的候有程,首先是分配存空,然后就是用造函行初始化。 所以的默造函,其是什么事情都不做的,只是了完成上面的那程而生的。 你自己定的造函是需要做一些事的。
[解决办法]
似乎是一样吧.
[解决办法]
trivial ctor在实例化时仅分配空间 因为既然ctor什么也不做 就不需要调用了
non-trivial ctor还要调用ctor 不管ctor多简单 至少有调用开销
在实例化大量对象时 会有明显效率提升
[解决办法]
#include <iostream>
#include <ctime>
using namespace std;
class CA {
public:
CA() {
}
};
class CB {
};
int main(int arg, char** argv) {
int startTime, endTime;
int length = 100000000;
startTime = clock();
for (int i= 0; i < length; i++) {
CA ca;
}
endTime = clock();
cout < < "defined constructor " < < (endTime - startTime) < < endl;
startTime = clock();
for (int i = 0; i < length; i++) {
CB cb;
}
endTime = clock();
cout < < "default constructor " < < (endTime - startTime) < < endl;
}
上面这小段程序测试了一下,自己写个什么也不做的构造函数与使用默认构造函数,在我机器上分配100000000个对象,时间相差60毫秒左右,也许是显示的调用构造函数的语句会比调用默认构造函数多一些指令吧,不过在大多数情况下,都会在构造函数中做一些初始化工作,所以其实这个问题不必要考虑,因为大多数都会用到自己写的构造函数.
[解决办法]
楼上的代码,用gcc加上-O2优化选项,上面的程序的输出基本一样,反汇编以后可以看到,循环里的东西都被优化掉了……
前两个clock调用之间的代码:
call_clock
movl%eax, %esi
movl$99999999, %eax
.p2align 4,,15
L6:
decl%eax
jnsL6
call_clock
后面两个clock调用之间的代码:
call_clock
movl%eax, %esi
movl$99999999, %eax
.p2align 4,,15
L19:
decl%eax
jnsL19
call_clock
结果是一样的。
如果不加优化选项,那么代码是下面这样的:
前两个clock调用之间的代码:
call_clock
movl%eax, -4(%ebp)
movl$0, -16(%ebp)
L11:
movl-16(%ebp), %eax
cmpl-12(%ebp), %eax
jgeL12
leal-17(%ebp), %eax
movl%eax, (%esp)
call__ZN2CAC1Ev
leal-16(%ebp), %eax
incl(%eax)
jmpL11
L12:
call_clock
后面两个clock调用之间的代码:
call_clock
movl%eax, -4(%ebp)
movl$0, -16(%ebp)
L14:
movl-16(%ebp), %eax
cmpl-12(%ebp), %eax
jgeL15
leal-16(%ebp), %eax
incl(%eax)
jmpL14
L15:
call_clock
明显前面两个clock之间多了几条指令,其中包含了call,就是调用CA的构造函数。
[解决办法]
看一看就行,知道就行,赞一个第一个举例子的人
[解决办法]
trivial类?
如果没有变量一定赋初值的习惯,那么随便。
如果有变量一定赋初值的习惯,那么,那就是有构造函数的non-trivial类。
实现相同的功能,C不会比C++效率有可值得讨论的优势。