i++ and ++i efficiency

其实这个问题,百度的话,有一大堆的参考资料,但是,在这里,我产生了一些困惑,他们所分析的结果,和我的测试代码不一致,这让我纠结了,所以,再次的写一下这个问题,顺顺思路。



我的测试环境:系统:Windows7 32bit,编程平台:Qt 5.3.1 (MSVC 2010,32bit)

首先说一下比较被大众所认可的结果:

(1)在自定义的数据类型的时候,因为前缀式(++i)可以返回对象的引用,而后缀式(i++),必须返回对象的数值,所以,导致在大的对象的时候产生了较大的复制开销,引起效率降低。所以,使用自定义的数据类型的时候,使用前缀式(++i)效率更好一些;

(2)如果是内置类型的,如int,效率是一样的。

(3)c++Primer上面有说:对于老旧的编译器++i效率好,对于好的编译器i++被优化了(效率一样)。表示该用哪个用哪个。



我的测试代码:

#include <iostream>
using namespace std;
//struct(1 data member)
struct oj
{
    int j;
}a;

//(2 data members) class
class oo
{
public:
    oo():a(0),b(0){}
    oo operator ++()//Prefix plus
    {
        ++a;
        ++b;
        return *this;
    }
    oo operator ++(int)//suffix plus
    {
        oo temp(*this);
        a++;
        b++;
        return temp;
    }
private:
    int a;
    int b;
};
int main()
{
    int i=0;
    int x=0;
    //Built-in data types
    i++;
    ++i;
    x=i++;
    x=++i;

    //struct(1 data member)
    a.j = 0;
    a.i = 0;
    a.j++;
    ++a.j;
    x = a.j++;
    x = ++a.j;

    //(2 data members) class
    oo o,ox;
    o++;
    ++o;
    ox = o++;
    ox = ++o;
    return 0;
}


最接近机器语言的汇编

(1)先分析内建的数据类型:

分析结果如下:

对于内建的数据类型,单独使用i++和++i是没有效率区分的。但是,表达式中的i++和++i是有区别的,如上图所示,所以对于内建的表达式中的,根据需求,含有++i的表达式的效率要好一些。(注意,这里我强调的是整个表达式的效率。而非单纯的i++ and ++i.)



(2)自定义的数据类型(结构体):

如测试代码,这里使用了结构体,包含一个数据成员。

分析结果如下:

对于一个结构体(包含有一个数据成员)的自定义数据类型而言,单独的a.j++ and ++ a.j的效率是一样的,没有什么可争论的。但是,对于表达式的中的 x = a.j++ and x = ++a.j,这个表达式的效率,结果确出现了和“自定义的数据类型中,++i的效率更好”的违背。原因图片中已经解释过了,所以,对于表达式中含有自增和自减运算符的,在讨论表达式的效率的时候,不能单纯的使用理论依据,还应该考虑自己的平台环境,编译器的指令集系统,这里我想到了精简指令集和复杂指令集。



(3)自定义数据类型(类,2个数据成员,重载++运算符)

分析结果:

对于类对象的自增运算,我们重载了运算符。从汇编代码来看,不管是单独使用,还是含有自增运算符的表达式,O++操作,因为有入栈和出栈操作,所以,显得效率有些不佳。但是,在这里,我们完全没有考虑重载函数的运行效率,这里只是显示了函数的调用。其实,这里不用深究重载函数的效率了,单从C++语言就可以看出来。前缀的++i的重载函数的效率更好一些。

2个重载函数的汇编代码对比(左边为++i前缀的重载,右边为i++后缀的重载):



自我总结:

这里,我不想说,i++ 和 ++i的效率哪一个更好,通过上面的测试代码,我们可以发现,对于不同的环境,不同的数据结构会有不同的效率。我想说的是,通过发现一个问题,然后寻找答案,质疑答案,验证答案的这个过程,让我学会了不少东西。也许我的验证方法是不科学的,但是从中我认真的对待过,从中,学会了阅读汇编代码,这使我更加深刻的理解了机器对于程序的运行机制是什么样的。认真对待问题,你会从中收获很多的。

如果有面试官问你这样的问题的话,可以如下回答:

内建的数据类型时,效率一样。
但是,在自定义的数据类型的时候,因为前缀式(++i)可以返回对象的引用,而后缀式(i++),必须返回对象的数值

所以,导致在大的对象的时候产生了较大的复制开销,引起效率降低。

所以,使用自定义的数据类型的时候,使用前缀式(++i);

同时,真的需要在细节上提高自己程序效率的话,你可以写个简单的测试用例,测试一下。因为在自己的平台上测试,相对准确一些。没必要,像我这么纠结。

时间: 2024-10-15 04:34:26

i++ and ++i efficiency的相关文章

C++对象模型对象成员的效率 (Object Mem ber Efficiency)(第三章) .

3.5 对象成员的效率 (Object Mem ber Efficiency) 下面某个测试,目的在测试聚合(aggregation).封装(encapsulation),以及继承(Inheritance)所引发的额外负荷的程度.所有测试都是以个别局部变量的加法,减法,赋值(assign)等操作的存取成本为依据.下面就是个别的局部变量: float pA_x = 1.725, pA_y = 0.875, pA_z = 0.478; float pB_x = 0.315, pB_y = 0.317

Test of returning array efficiency from Fortran subprograms

Fortran has two kinds of subprograms: subroutine and function. Usually, subroutine is a combination of several procedures generating side effects without returning values, while the purpose of function is to return values after some operations. In fa

I.MX6 working note for high efficiency

/**************************************************************************** * I.MX6 working note for high efficiency * * 主要是将在I.MX6 Android工作中的用到的特殊需求用法的记录,并对boot.img * 分解.合成进行了说明,另外增加了一个shell脚本自动完成boot.img合成与拷贝. * * 深圳 南山平山村 晴 2015/05/13 周三 曾剑锋 **

POJ 1252 Euro Efficiency

背包 或者 BFS 题意是说给你几种基本货币,组成 1~100 内所有的钱,用最少的基本货币使用量. 输出 使用量的概率,和最大的使用量. 可以BFS 也可以 背包. 不过记得数组开大点. 可能会出现 100 = 99+99 -98 的情况. 背包是先做一个完全背包,求得最少可能由多少相加. 然后做一个 01背包,看能否被 减. 背包: #include<cstdio> #include<cstring> #include<string> #include<que

C++对象模型——对象成员的效率 (Object Member Efficiency)(第三章)

3.5 对象成员的效率 (Object Mem ber Efficiency) 以下某个測试,目的在測试聚合(aggregation).封装(encapsulation),以及继承(Inheritance)所引发的额外负荷的程度.全部測试都是以个别局部变量的加法,减法,赋值(assign)等操作的存取成本为根据.以下就是个别的局部变量: float pA_x = 1.725, pA_y = 0.875, pA_z = 0.478; float pB_x = 0.315, pB_y = 0.317

PP- Work center -- Key for performance Efficiency Rate

Purpose : Performance Efficiency Rate Key Performance efficiency rate keys are assigned in the Basic data screen of the work center to thestandard values. The performance efficiency rate key is the ratio between an individual's actual output and the

Hardware Scaler for Performance and Efficiency

If you develop a performance-intensive 3D game, you're always looking for ways to give users richer graphics, higher frame rates, and better responsiveness. You also want to conserve the user's battery and keep the device from getting too warm during

Euro Efficiency(完全背包)

Euro Efficiency Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Java/Other) Total Submission(s) : 12   Accepted Submission(s) : 3 Problem Description On January 1st 2002, The Netherlands, and several other European countries aban

论文学习:Overview of the High Efficiency Video Coding Standard

Souce IEEE TRANSACTIONS ON CIRCUITS AND SYSTEMS FOR VIDEO TECHNOLOGY, VOL. 22, NO. 12, DECEMBER 2012 Background (2012) HEVC is currently being prepared as the newest video coding standard of the ITU-T Video Coding Experts Group and the ISO/IEC Moving

Efficiency in Shell

最近在写一个shell脚本, 由于该脚本对效率有较高的要求, 所以查阅了一些文章. 感觉这篇文章写得确实不错, 文章中的例子,确实很棒! 所 以我把他们提取出来: @1:实例: 需求:计算1到100000累加结果 方法1:采用bash  shell的数值计算 # time for((i=0;i<=100000;i++)); do ((sum+=i)); done ; echo $sum real    0m1.134s user    0m1.080s sys     0m0.048s 5000