有关C++中trivial和non-trivial构造函数的问题【C和C++效率问题后续4】

wanilyer 2007-06-28 11:52:53
众所周知,trivial比non-trivial构造函数在实例化一个类时速度要快许多。
对于下面这个类
class A
{
int i;
}

如果自己显式的定义一个构造函数那就成了non-trivial构造函数,那么在同样实例化一个A的对象时就会慢许多,(如:A a)。

现在想请问,它为什么会慢?也就是non-trivial比trivial构造函数多干了什么事情?
...全文
659 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
似乎是一样吧.
agaric 2007-06-28
  • 打赏
  • 举报
回复
我的理解, 建立一個對象的時候有兩個過程,首先是分配內存空間,然后就是調用構造函數進行初始化。 所以的默認構造函數,其實應該是什么事情都不做的,只是為了完成上面的那個過程而產生的。 你自己定義的構造函數總是需要做一些事的。
taodm 2007-06-28
  • 打赏
  • 举报
回复
trivial类?
如果没有变量一定赋初值的习惯,那么随便。
如果有变量一定赋初值的习惯,那么,那就是有构造函数的non-trivial类。
实现相同的功能,C不会比C++效率有可值得讨论的优势。
xshhe82 2007-06-28
  • 打赏
  • 举报
回复
看一看就行,知道就行,赞一个第一个举例子的人
sjdf 2007-06-28
  • 打赏
  • 举报
回复
楼上的代码,用gcc加上-O2优化选项,上面的程序的输出基本一样,反汇编以后可以看到,循环里的东西都被优化掉了……

前两个clock调用之间的代码:
call _clock
movl %eax, %esi
movl $99999999, %eax
.p2align 4,,15
L6:
decl %eax
jns L6
call _clock

后面两个clock调用之间的代码:
call _clock
movl %eax, %esi
movl $99999999, %eax
.p2align 4,,15
L19:
decl %eax
jns L19
call _clock

结果是一样的。
如果不加优化选项,那么代码是下面这样的:

前两个clock调用之间的代码:
call _clock
movl %eax, -4(%ebp)
movl $0, -16(%ebp)
L11:
movl -16(%ebp), %eax
cmpl -12(%ebp), %eax
jge L12
leal -17(%ebp), %eax
movl %eax, (%esp)
call __ZN2CAC1Ev
leal -16(%ebp), %eax
incl (%eax)
jmp L11
L12:
call _clock

后面两个clock调用之间的代码:
call _clock
movl %eax, -4(%ebp)
movl $0, -16(%ebp)
L14:
movl -16(%ebp), %eax
cmpl -12(%ebp), %eax
jge L15
leal -16(%ebp), %eax
incl (%eax)
jmp L14
L15:
call _clock

明显前面两个clock之间多了几条指令,其中包含了call,就是调用CA的构造函数。
wanilyer 2007-06-28
  • 打赏
  • 举报
回复
构造函数写与不写在有些情况下是有区别的。看看ls的测试就知道了。《深度探索C++对象模型》一书就有很详细的讲述。

关于sining520说的比较合理。赞一个!

不过不知道还有没有其他的说法?
Inhibitory 2007-06-28
  • 打赏
  • 举报
回复
#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毫秒左右,也许是显示的调用构造函数的语句会比调用默认构造函数多一些指令吧,不过在大多数情况下,都会在构造函数中做一些初始化工作,所以其实这个问题不必要考虑,因为大多数都会用到自己写的构造函数.
  • 打赏
  • 举报
回复
编译器有个著名的功能,叫做优化,很多时候你写和不写是没区别的
sining520 2007-06-28
  • 打赏
  • 举报
回复
trivial ctor在实例化时仅分配空间 因为既然ctor什么也不做 就不需要调用了
non-trivial ctor还要调用ctor 不管ctor多简单 至少有调用开销
在实例化大量对象时 会有明显效率提升

64,281

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧