如何写出优质的C++代码:(七)最大限度提高程序执行效率

我们在声明一个变量的时候,会伴随着对该变量构造函数的执行,当程序跳出变量作用域的时候,又会执行变量的析构函数,对于一些比较复杂的对象,这是一笔不小的开支,为此,我们应尽量避免一些没有用到的变量的定义,看看下面这段代码:

std::string ExampleFun(const std::string& strParam)
{
    std::string strRet;
    if(......)            
        {......}        //在执行期间,可能抛出异常
    return strRst;
}

我们希望通过ExampleFun函数得到一个字符串strRet,如果在函数体内程序抛出异常,函数可能最终在if的执行语句内就返回了,而strRet没有被使用,此时就白白付出了对strRet的构造和析构的成本。较好的做法应该是:

    if(......)            
        {......}     
    std::string strRet;
    ......
    return strRst;

我们也经常在循环中需要使用一些临时变量,该如何写呢:

//方法A
Widget w;
for(int i = 0;i < 10000;i++)
{
    //对w进行操作
    ......
}

//方法B
for(int i = 0;i < 10000;i++)
{
    Widget w;
    //对w进行操作
    ......
}

对比方法A和方法B,不难看出,

方法A:1次构造 + 1次析构 + n次复制操作;

方法B:1000次构造 + 10000次析构;

我们需要对方法A和方法B的执行效率做客观的分析,如果Widget的构造和析构的成本大于复制操作的成本,则方法A更优,反之,则方法B更优。

类型转换也会影响程序执行效率,许多程序员相信,转型其实什么都没有做,只是告诉编译器把某种类型视作另一种类型。这种想法是错误的,任何类型转换都需要编译器编译出运行期间的执行代码。看看下面的代码:

//基类
class CBase
{
    ......
	void func1();
};
//派生类1
class CSon1 : public CBase
{    
    ......
	void func1();
};
//其他的派生类
class CSon2 : public CBase{};
class CSon3 : public CBase{};
class CSon4 : public CBase{};

在这里我们写了一个基类CBase和派生至它4个类,每一个类中都含有func1()函数。现在,我们希望执行CSon1中的func1()函数,为此,我们声明了每一个类的指针,并将这些指针放入到一个容器中:

typedef std::vector<std::shared_ptr<CBase>> VPE;
VPE expPtrs;
...            //将每个子类的指针放入容器中
for(VPE::iterator iter = expPtrs.begin();iter != expPtrs.end();++iter)
{
    if(CSon1 *ptr = dynamic_cast<CSon1*>(iter->get()))
        (*ptr)->func1();
}

尽管这种写法没有错,能够编译通过,但是,这样的写法是非常不提倡的,程序会遍历容器里的每一个元素,并对其做类型转换,会严重影响程序的执行效率。

有一种办法,我们可以将容器的类型写成CSon1,就可以避免类型转型:

typedef std::vector<std::shared_ptr<CSon1>> VPE;
...            //将每个子类的指针放入容器中
for(......)
{
        (*ptr)->func1();
}

但是这也会带来另一个弊端,如果我们要调用多个派生类的func1()函数,就需要声明多个容器,解决办法是,我们可以将func1()定义成virtual函数:

//基类
class CBase
{
    ......
	virtual void func1();
};
//派生类1
class CSon1 : public CBase
{    
    ......
	virtual void func1();
};

typedef std::vector<std::shared_ptr<CBase>> VPE;
VPE expPtrs;
...            //将每个子类的指针放入容器中
for(VPE::iterator iter = expPtrs.begin();iter != expPtrs.end();++iter)
{
        (*ptr)->func1();
}

综上,转型会消耗程序的执行效率,程序中尽量避免强制转型,找到无需转型的替代方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值