动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
电脑书籍下载:程序设计书籍 | 数据库教程书籍 | 平面与多媒体书籍 | 网络通讯书籍 | 系统管理书籍 | 网络安全书籍 | 认证考试书籍
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > C/C++教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ C/C++教程 ]的信息



本月文章推荐
.大家进来瞧瞧我编的小迷宫,望大.
.Shell实现Unix进程间信息交换的几.
.C语言程序开发经典实例之二.
.文件加密一例.
.BCB中实现动态创建组件.
.高质量C++/C编程指南 --&nb.
.vb.net中windows服务的创建.
.WINDOWS键盘事件的挂钩监控原理及.
.TLocateOptions的用法.
.来研究一下yahoo的酷图幻灯js代码.
.C语言教程第七章:结构与联合.
.在 C++ 中控制Windows关机.
.使非MFC窗口程序的窗口回调过程成.
.C/C++中数组和指针类型的关系的入.
..
.Visual FoxPro 9.0 的报表设计器.
..
.指针变量的定义与引用.
.在C++中处理错误的方法.
.在Visual Studio.NET中使用Cryst.

C++的效率浅析

发表日期:2008-3-8 |


       
  自从七十年代C语言诞生以来,一直以其灵活性、高效率和可移植性为软件开发人员所钟爱,成为系统软件开发的首选工具。而C++作为C语言的继续和发展,不仅保留了C语言的高度灵活、高效率和易于理解等诸多优点,还包含了几乎所有面向对象的特征,成为新一代软件系统构建的利器。

  相对来说,C语言是一种简洁的语言,所涉及的概念和元素比较少,主要是:宏(macro)、指针(pointer)、结构(strUCt)、函数(function)和数组(array),比较轻易把握和理解。而C++不仅包含了上面所提到的元素,还提供了私有成员(private members)、公有成员(public members)、函数重载(function overloading)、缺省参数(default parameters)、构造函数、析构函数、对象的引用(references)、操作符重载(operator overloading)、友元(friends)、模板(templates)、异常处理(exceptions)等诸多的要素,给程序员提供了更大的设计空间,同时也增加了软件设计的难度。

  C语言之所以能被广泛的应用,其高效率是一个不可忽略的原因,C语言的效率能达到汇编语言的80%以上,对于一种高级语言来说,C语言的高效率就不言而喻了。那么,C++相对于C来说,其效率如何呢?实际上,C++的设计者stroustrup要求C++效率必须至少维持在与C相差5%以内,所以,经过精心设计和实现的C++同样有很高的效率,但并非所有C++程序具有当然的高效率,由于C++的非凡性,一些不好的设计和实现习惯依然会对系统的效率造成较大的影响。同时,也由于有一部分程序员对C++的一些底层实现机制不够了解,就不能从原理上理解如何提高软件系统的效率。

  本文主要讨论两个方面的问题:第一,对比C++的函数调用和C函数调用,解析C++的函数调用机制;第二,例举一些C++程序员不太注重的技术细节,解释如何提高C++的效率。为方便起见,本文的讨论以下面所描述的单一继续为例(多重继续有其非凡性,另作讨论)。

class X
{
public:
virtual ~X(); //析构函数
virtual void VirtualFunc(); //虚函数
inline int InlineFunc() { return m_iMember}; //内联函数
void NormalFunc(); //普通成员函数
static void StaticFunc(); //静态函数
private:
int m_iMember;

};

class XX: public X
{
public:
XX();
virtual ~XX();
virtual void VirtualFunc();
private:
String m_strName;
int m_iMember2;

};

  C++的的函数分为四种:内联函数(inline member function)、静态成员函数(static member function)、虚函数(virtual member function)和普通成员函数。

  内联函数类似于C语言中的宏定义函数调用,C++编译器将内联函数的函数体扩展在函数调用的位置,使内联函数看起来象函数,却不需要承受函数调用的开销,对于一些函数体比较简单的内联函数来说,可以大大提高内联函数的调用效率。但内联函数并非没有代价,假如内联函数体比较大,内联函数的扩展将大大增加目标文件和可运行文件的大小;另外,inline要害字对编译器只是一种提示,并非一个强制指令,也就是说,编译器可能会忽略某些inline要害字,假如被忽略,内联函数将被当作普通的函数调用,编译器一般会忽略一些复杂的内联函数,如函数体中有复杂语句,包括循环语句、递归调用等。所以,内联函数的函数体定义要简单,否则在效率上会得不偿失。

  静态函数的调用,如下面的几种方式:

X obj; X* ptr = &obj;
obj.StaticFunc();
ptr->StaticFunc();
X::StaticFunc();

  将被编译器转化为一般的C函数调用形式,如同这样:

mangled_name_of_X_StaticFunc();
   //obj.StaticFunc();
mangled_name_of_X_StaticFunc();
   // ptr->StaticFunc();
mangled_name_of_X_StaticFunc();
  // X::StaticFunc();

  mangled_name_of_X_StaticFunc()是指编译器将X::StaticFunc()函数经过变形(mangled)后的内部名称(C++编译器保证每个函数将被mangled为独一无二的名称,不同的编译器有不同的算法,C++标准并没有规定统一的算法,所以mangled之后的名称也可能不同)。可以看出,静态函数的调用同普通的C函数调用有完全相同的效率,并没有额外的开销。

  普通成员函数的调用,如下列方式:

X obj; X* ptr = &obj;
obj.NormalFunc();
ptr->NormalFunc();

  将被被编译器转化为如下的C函数调用形式,如同这样。

mangled_name_of_X_NormalFunc(&obj);
   //obj.NormalFunc();
mangled_name_of_X_NormalFunc(ptr);
// ptr->NormalFunc();



  可以看出普通成员函数的调用同普通的C调用没有大的区别,效率与静态函数也相同。编译器将重新改写函数的定义,增加一个const X* this参数将调用对象的地址传送进函数。

  虚函数的调用稍微复杂一些,为了支持多态性,实现运行时刻绑定,编译器需要在每个对象上增加一个字段也就是vptr以指向类的虚函数表vtbl,如类X的对象模型如下图所示(本文中对此不多做解释,若想进一步了解,可以参考其它材料)。

C++的效率浅析


  虚函数的多态性只能通过对象指针或对象的引用调用来实现,如下的调用:

X obj;
X* ptr = &obj; X& ref = obj;
ptr->VirtualFunc();
ref.VirtualFunc();

  将被C++编译器转换为如下的形式。

( *ptr->vptr[2] )(ptr);
( *ptr->vptr[2] )(&ref);



  其中的2表示VirtualFunc在类虚函数表的第2个槽位。可以看出,虚函数的调用相当于一个C的函数指针调用,其效率也并未降低。

  由以上的四个例子可以看出,C++的函数调用效率依然很高。但C++还是有其非凡性,为了保证面向对象语义的正确性,C++编译器会在程序员所编写的程序基础上,做大量的扩展,假如程序员不了解编译器背后所做的这些工作,就可能写出效率不高的程序。对于一些继续层次很深的派生类或在成员变量中包含了很多其它类对象(如XX中的m_strName变量)的类来说,对象的创建和销毁的开销是相当大的,比如XX类的缺省构造函数,即使程序员没有定义任何语句,编译器依然会给其构造函数扩充以下代码来保证对象语义的正确性:

XX::XX()
{
// 编译器扩充代码所要做的工作

1、 调用父类X的缺省构造函数
2、 设定vptr指向XX类虚函数表
3、 调用String类的缺省构造函数构造m_strName
};



  所以为了提高效率,减少不必要的临时对象的产生、拖延暂时不必要的对象定义、用初始化代替赋值、使用构造函数初始化列表代替在构造函数中赋值等方法都能有效提高程序的运行效率。以下举例说明:

  1、 减少临时对象的生成。如以传送对象引用的方式代替传值方式来定义函数的参数,如下例所示,传值方式将导致一个XX临时对象的产生

效率不高的做法     高效率做法
void Function( XX xx ) void Function( const XX& xx )
{ {
//函数体 //函数体
} }



  2、 拖延暂时不必要的对象定义。在C中要将所有的局部变量定义在函数体头部,考虑到C++中对象创建的开销,这不是一个好习惯。如下例,假如大部分情况下bCache为"真",则拖延xx的定义可以大大提高函数的效率。

效率不高的做法 高效率做法
void Function( bool bCache ) void Function( bool bCache )
{ {
//函数体 //函数体
XX xx; if( bCache )
if( bCache ) {// do something without xx
{ return;
// do something without xx }
return;
}
//对xx进行操作 XX xx;
//对xx进行操作

return; return;
} }



  3、 可能情况下,以初始化代替先定义后赋值。如下例,高效率的做法会比效率不高的做法省去了cache变量的缺省构造函数调用开销。

效率不高的做法 高效率做法
void Function( const XX& xx ) void Function( const XX& xx )
{ {
XX cache; XX cache = xx;
cache = xx ;
} }



  4、 在构造函数中使用成员变量的初始化列表代替在构造函数中赋值。如下例,在效率不高的做法中,XX的构造函数会首先调用m_strName的缺省构造函数,再产生一个临时的String object,用空串""初始化临时对象,再以临时对象赋值(assign)给m_strName,然后销毁临时对象。而高效的做法只需要调用一次m_strName的构造函数。

效率不高的做法 高效率做法
XX::XX() XX::XX() : m_strName( "" )
{ {
m_strName = ""; …

} }

  类似的例子还很多,如何写出高效的C++程序需要实践和积累,但理解C++的底层运行机制是一个不可缺少的步骤,只要平时多学习和思考,编写高效的C++程序是完全可行的。



上一篇:关于拷贝构造函数和赋值运算符 人气:376
下一篇:Win32下两种用于C++的线程同步类(下) 人气:246
浏览全部C/C++的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-7-6 飞天论坛FTBBS ASP v6.3 Build 0
2008-7-6 飞天论坛FTBBS ASP v6.3 Build 0
2008-7-6 飞天论坛FTBBS ASP v6.8 Build 0
2008-7-6 讯息内容管理系统 v2.1
2008-7-6 三五电影程序 v2.0
2008-7-6 神鹰腾讯小说小偷 v3.0
2008-7-6 EasyIDE Framework v1.0 Build 2
2008-7-6 品告CMS系统(电影版) v0.9
2008-7-6 QQ自动登录器 C# 源码 v1.0
2008-7-5 AgileMessenger即时通讯工具 v1.
2008-7-5 GoodCalculator2.0版固件计算器
2008-7-5 RepoName源地址搜索工具 v1.21b
2008-7-5 AgileMessenger即时通讯工具 v1.
2008-7-5 TouchCopy多媒体管理软件 v3.13完
2008-7-5 VideosTone视频铃声 v1.1汉化破解
2008-7-5 TouchPad触摸板 v4.44破解版
2008-7-5 VideosTone破解补丁 v1.0
2008-7-5 Feeds GoogleReader客户端 v0.4.3


  发表评论
姓 名: 验证码:
内 容:
[ 汉字翻译拼音 ] [ 广告代码 ] [ 符号对照表 ] [ 进制转换 ] [ 经典小工具 ] [ 个税计算 ] [ 汉字简繁转换 ] [ 普通单位换算 ] [ 公制单位换算 ]
[ 生辰老黄历 ] [ 国内电话区号 ] [ 国家代码与域名缩写 ] [ 文字加密解密 ] [ 健康查询 ] [ 万年历 ] [ 手机号码查询 ] [ ip搜索 ] [ Google PR查询 ]
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報