C和C++在效率问题上有哪些差异

摘自:http://www.programfan.com/club/showpost.asp?id=23945



【taodm】:
实现同样的OO特性,C++比C快。
不使用OO特性,C++和C一样快。
具体去看《深度探索C++对象模型》

【VCLIFE】:
关注,  不使用OO特性,C++和C一样快。//貌似C快,当然C++中你全写C的代码,那当然一样快了

【zhaotao0982】:
快慢问题主要取决于你的软件质量,这个应该比较实际,讨论那些那个快,实际意义不大,我感觉

【akirya】:
看代码了,写的好的C++代码要不会和C差多少的

【xlbdan】:
C++代码写的好的情况下是比C慢不了多少的,

但总的来说在大部分情况下还是C要快一些的.

其实也是因为C和C++本身面向的开发就不同的原因.

C++一般用来做大型的对象操作等等,中间有许多的构造析构等过程,当然要慢一些.

而C一般用来处理非对象性质的操作,就没有那么多的构造析构时间.

但我觉得,有的东西,C++慢,但C做不了,还是要用C++去做

有的东西,C和C++都能做的,想要速度,就用C好了

【jixingzhong】:
基本上差不多 。。。。

【jinwei1984】:
LS的讲解详细!

【duguguiyu1984】:
大部分时候是没有太大区别的。只是用到一些特殊的OO特征时会损失一些性能,比如虚继承等。

【iamcaicainiao】:
稍微详细点说.
正常的c++类.不带virtual函数,不带virtual继承的.跟c里一样快.

当带上了virtual,就得付出点代价了.


【jixingzhong】:
http://www.bagley.org/~doug/shootout/  
   
  参见这个网站对数十种语言的比较。  
  C和/C++的差别并不是很大,CPU   10-20%左右,Memory   30-50%左右

【jixingzhong】:
【REF】
一般来说,C++写的程序总是比C的要慢,而且占用的体积要大。这是因为:  
  1。动态多态性在C++中是用虚拟函数表实现的;  
  2。C++中的函数和操作符很多都是在原有的C函数上加了一层,比如new   和   delete;  
  3。C++中的函数会在传递参数和返回值时构造临时对象,这额外的增加构造和析构函数的开销;  
  但是总体来说,差别不是很大。但是C++的抽象和表达能力是C远远不及的,也是任何其他编程语言远远不及的。在使用C++时,如果你对C/C++语言的底层机制比较了解的话,就应该在程序的性能瓶颈处的代码加以优化。这样才能写处好的程序。

C/C++/Perl/汇编/Java效率比较:
http://www.maikr.com/kan.aspx?id=cb73285e-b1c9-48e2-9ab1-0177bc9da430

【kingsun555】:
BJARNE 在设计C++的时候,就把C++的性能看的很重要。C与C++的效率方面的差距不超过5%。

【Vitin】:
C/C++/Perl/汇编/Java效率比较:
http://www.maikr.com/kan.aspx?id=cb73285e-b1c9-48e2-9ab1-0177bc9da430

--------------------------------------------------------------------------

看过这篇了,还是有一些道理的。
不过这个例子只能做参考,在一些方面有意义,但不能成为语言效率的可靠依据。原因如下:
1、这个例子是以读取文件为基础的,读取文件的速度很大程度上依赖操作系统,而不是语言本身。
2、各语言使用了不同的读法。C和汇编时读入大缓冲区,而其他是读一行。对读文件的效率而言,缓冲区大小(从而影响读取次数)是关键因素。C比汇编快也因为它使用了更大的缓冲区。

因为这两点,这个例子的数据不足以说明语言的效率问题。但是它告诉我们,即使语言提供了多高的效率,很大程度上还要看使用方法。

【Wolf0403】:
1、你需要解决什么问题?哪种语言能够方便解决?
2、你需要怎样的效率?范围?精度?
3、你对两种语言的掌握程度如何?
4、是否有合适的性能分析和调节工具辅助支持你的研究?

不回答上面的问题,提这个问题是没有意义的。

【xlbdan】:
总的来说感觉写和底层关系密切的代码还是用C比较好,

和应用相关方面用C++写更好一些,

毕竟现在面向对象做应用还是比面向过程吃香

【Chiyer】:


<An empirical comparison of C, C++, Java, Perl, Python, Rexx, and Tcl>

http://page.mi.fu-berlin.de/~prechelt/Biblio/jccpprt_computer2000.pdf

【Vitin】:
LS这篇比较全面,学习。

【wanilyer】:
首先非常感谢大家:

to 晨星。

2。C++中的函数和操作符很多都是在原有的C函数上加了一层,比如new   和   delete; 

>>对于您所说的这一点,我不是太理解,能否在给我讲讲?谢谢!

to 卫亭

即使语言提供了多高的效率,很大程度上还要看使用方法。
>>对于这个,我很赞同,不过我们现在想知道,C++的效率到底比C差多少,到底在哪些方面差,C++的效率损失是否能够忍受,这样我才好在C++和C的方面做出选择,同时也能够避免C++一些不必要的损失。

to wolf0403
1、你需要解决什么问题?哪种语言能够方便解决?
解决的问题可能是索引问题(搜索引擎相关的),但是现在也没有指定具体问题,所以就当作是一个纯理论研究,不考虑代码编写人的功力,不考虑具体功能。把这些都理论化的情况下。

2、你需要怎样的效率?范围?精度?
效率当然是越高越好,虽然这个话说了等于白说。

3、你对两种语言的掌握程度如何?
这个还真不好说。使用C++两年了吧,对OO和泛型有比较深的了解,但是纯C用的比较少。

4、是否有合适的性能分析和调节工具辅助支持你的研究?
这个我还真没有,也不知道该怎么测试C和C++的性能,怎么样写代码才叫纯C代码,怎么样写代码就是C++代码了,还望赐教。测试C和C++的性能暂时不考虑OO特性(我觉得这个比较没有太多意义),只考虑抽象数据编程模式和纯C的效率。



【wanilyer】:
对于上面补充一个问题?

在calss或者struct中写入构造函数和不写构造函数,同样申明一个类变量,开销是不同的。不写构造函数申明类变量明显要快很多,这个是否可以算作是C和C++效率的区别?

还有拷贝构造函数和不写拷贝构造函数对于类变量的赋值也是不同的。
calss A {...}

A a ;         1
A b = a;      2

对于第2句,不写拷贝构造函数执行的更快,不知是何原因。

【Chiyer】:


struct st {

    int a;

    st() {a = 0;}
    st(st& _t) {

        a = _t.a;
    }

};


void main()
{
    st t1;
    st t2 = t1;
}

/*

无拷贝构造函数

st t2 = t1;
00412E16  mov         eax,dword ptr [t1] 
00412E19  mov         dword ptr [t2],eax 

有拷贝构造函数

st t2 = t1;
00412E16  lea         eax,[t1] 
00412E19  push        eax  
00412E1A  lea         ecx,[t2] 
00412E1D  call        st::st (4111D6h) 

*/



看出不写拷贝构造函数执行的更快的原因了吧

【Chiyer】:
没有拷贝构造函数的时候直接拷贝内容

有的时候调用拷贝构造函数

【wanilyer】:
请问ls,你那些汇编代码是怎么看到的?用的什么编译器。

【chang_chunhua】:
讲的真好。

【Chiyer】:
请问ls,你那些汇编代码是怎么看到的?用的什么编译器。

------


我用的是vs2005 不记得以前的版本怎么看的了

vs2005里

先在你要看的代码那里断点,f5运行断在那里的时候,

点鼠标又键-》go to disassembly

【longshanks】:
如果考虑到C++的inline,在某些情况下,效率会比C高,当然此时执行代码尺寸大不少。
构造函数的确是造成C++性能不及C的一个原因。但并非不写构造函数就能提高性能。因为有时编译器会偷偷地生成一个非平凡的构造函数:
class X
{
public:
   string a;
};
所以,确切地说是pod类型,plain old data,比非pod类型效率高。

【wanilyer】:
首先谢谢星羽

to longshanks
对的,我做测试的时候只用了基本类型。在用到非基本数据类型时,确实是会生成一个非平凡构造函数的。

不过对于inline这个东西我并不怎么看好,inline函数的调用比全局函数调用以及静态成员函数调用的开销都要大。它和C++(简单C++类,无虚拟机制,无继承)的成员函数效率差不多。不知道您所说的inline比C快是指哪些情况?而且我也曾经听说过一句话叫做:“C++的成员函数一般情况下会优化为内联”。不知是否正确?以至于我在我的C++代码中很少显式的写上inline这个关键字。

【longshanks】:
to wanilyer(缘随影去) :
是这样的,函数inline之后,并且编译器允许inline,那么,函数会整个地在调用位置就地展开。就仿佛没有调用函数一样。相比标准函数的调用,inline省去了函数调用时的栈操作,包括参数压栈、寄存器压栈、栈清理等等。并且,由于函数代码就地展开,编译器在优化时可以将inline函数代码和调用方代码作为一个整体考虑,进一步加以优化。这一点标准函数是做不到的。
需要强调的是,inline不是强制的。某些编译器可能会不执行inline。但现在主流的编译器,如g++、vc、bcb等等都积极地执行inline。即便如此,inline并非总是执行的,比如递归的函数,编译器就拒绝inline,因为这种inline是做不到的。
编译器对inline的支持如何,需要参考相关文档,或者做些实验。而且,通常在debug状态下,inline是不做的,只有release编译,才会执行。
所有类型的函数都可以标记成inline,包括全局函数、成员函数、static函数。对于直接定义在class或struct中的成员函数,默认inline。如果定义在class/struct外的,则必须要通过inline关键字指定:
class A
{
void f1() {...} //inline
void f2();
inline void f3();
};
void A::f2() {...} //非inline
inline void f3() {...} //inline
最后,inline有一个有趣的现象。考虑如下函数:
int a[100];
inline void fill_a(int v) {
   if(v==0)
      return;
   a[v]=v*10;
   fill_a(v-1);
}
fill_a(9);//希望inline展开
尽管使用了inline关键字,但编译器是不会inline的。但是,inline还是可以做到的:
template<int n>
struct fill_a
{
    void operator()() {
       a[n]=n*10;
       fill_a<n-1>()();   //递归
    }
}
template<>
struct fill_a<0>
{
    void operator()() {
       a[0]=0;
    }
}
fill_a<9>()();
此时,fill_a<9>()();编译后(优化打开)的代码可能是这样的(伪码):
a[9]=90;
a[8]=80;
...
a[0]=0;
这样,便实现了递归的inline。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值