为什么说++i的效率比i++高?

开发 后端 开发工具
++i和i++这两个表达式从我们初学编程语言的时候就会接触到。前者是自增后取值,后者是取值后自增。不知道你是否听说过++i比i++快的说法,真的如此吗?

不知道你是否听说过++i比i++快的说法,真的如此吗?

++i与i++的区别

这两个表达式从我们初学编程语言的时候就会接触到。前者是自增后取值,后者是取值后自增。

我们看一个简单的例子。

  1. #include <iostream> 
  2. using namespace std; 
  3. int main() 
  4.     int a = 0
  5.     int b = 0
  6.     int c = a++;//int tmp = a;c=a;aa = a + 1 
  7.     int d = ++b;//bb = b + 1;d = b
  8.     cout<<"c="<<c<<";d="<<d<<endl
  9.     return 0; 

运行结果:

  1. c=0;d=1   

对于这个结果我们并不感到意外。

另外我们还注意到另外一个有意思的现象:

  1. #include <iostream> 
  2. using namespace std; 
  3. int main() 
  4.     int a = 0
  5.     int b = 0
  6.     int *c = &(a++); 
  7.     int *d = &(++b); 
  8.     return 0; 

编译后报错:

  1. main.cpp:7:19: error: lvalue required as unary ‘&’ operand 
  2.      int *c = &(a++); 

说&作用于左值,也就是说a++的结果并非左值。但++b的结果是左值。

可简单理解左值和右值:

  • 左值,有名对象,可赋值
  • 右值,临时对象,不可被赋值

运算符重载

通过前面的例子也发现了,对于内置类型,前置自增返回对象的引用,而后置自增返回对象的原值(但非左值)。

基于上述原则,一个前置版本和后置版本的常见实现如下:

  1. class Test 
  2. public: 
  3.     Test& operator++();//前置自增 
  4.     const Test operator++(int);//后置自增 
  5. private: 
  6.     int curPos; //当前位置 
  7. }; 
  8. /*前置自增实现范式*/ 
  9. Test& Test::operator++() 
  10.     ++curPos;      //自增 
  11.     return *this;  //取值 
  12. /*后置自增实现范式,为了与前置区分开,多了一个int参数,但从来没用过*/ 
  13. const Test Test::operator++(int) 
  14.     Test tmp = *this;  //取值 
  15.     ++curPos;             //自增 
  16.     return tmp; 

仔细观察后,我们发现前置自增,先自增,后返回原对象的对象;没有产生任何临时对象;而后置自增,先保存原对象,然后自增,最后返回该原临时对象,那么它就需要创建和销毁,这样一来,效率孰高孰低就很清楚了。

在不进行赋值的情况下,内置类型前置和后置自增的汇编都是一样的呢!

  1. void test() 
  2.   int i = 0
  3.   i++; 
  4.   //++i; 

汇编:

  1. push    rbp 
  2. mov     rbp, rsp 
  3. mov     DWORD PTR [rbp-4], 0 
  4. add     DWORD PTR [rbp-4], 1 
  5. nop 
  6. pop     rbp 
  7. ret 

不过,赋值的情况下,并且不开启编译器优化,它们的汇编代码还是有差别的,有兴趣的可以试试。

总结

对于内置类型,前置和后置自增或者自减在编译器优化的情况下,两者并无多大差别,而对于自定义类型,如无特别需要,人们似乎更加偏爱前置自增或自减,因为后置自增常常会产生临时对象。

但是,又能提高多少效率呢?

 

责任编辑:赵宁宁 来源: 编程珠玑
相关推荐

2021-08-02 09:31:20

Python工具代码

2021-11-24 07:56:56

For i++ ++i

2020-07-09 09:56:48

Python语言开发

2024-01-31 23:47:17

i++++i编码

2016-12-14 12:02:01

StormHadoop大数据

2017-02-14 14:20:02

StormHadoop

2022-05-10 15:59:44

split lock虚拟化

2021-10-13 06:49:15

网络 IO

2022-09-23 10:58:44

谷歌员工生产力大O表示

2014-03-27 15:01:50

算法C++

2021-05-12 08:15:53

HTTPSHTTP安全

2020-07-16 15:20:13

switch...caif...else语言

2020-07-22 08:01:41

Python开发运算符

2023-09-28 08:21:20

i++++i高并发

2017-12-19 16:24:20

2017-12-28 14:39:06

电脑IO

2020-02-24 12:34:21

JuliaPython编程语言

2015-08-26 10:37:13

云主机物理机服务器故障

2013-05-16 11:34:27

Google苹果

2023-09-03 22:44:28

I/O高并发
点赞
收藏

51CTO技术栈公众号