i++ i+=1 i=i+1哪个更快?为什么?

时间:2022-08-28 03:01:20
如题!
那一条语句执行起来会更快?更有效率?WHY?
想知道原因,

27 个解决方案

#1


没经证实的:
i++ : inc i

i+=1,i = i+1: 
      mov eax,i
      add eax,1
      mov i,eax

#2


好像一样

#3


++i 最快
i++ 次之,多用一个临时变量
i+=1 第三,需要取地址
i = i+1 最后,并多用一个临时变量

#4


等价,在编译器看来,代码都等价,没有区别

#5


以80386为例:

++i; // leal -4(%ebp), %eax
// incl (%eax)
i++;// leal -4(%ebp), %eax
// incl (%eax)
i=i+1;// leal -4(%ebp), %eax
// incl (%eax)
所以, 上面3个表达是一样.

换一下(leal: 2周期; movl: 4周期; incl: 1周期):
a=++i; //leal -4(%ebp), %eax
//incl (%eax)
//movl -4(%ebp), %eax
//movl %eax, -8(%ebp)
//movl -4(%ebp), %eax
总共: 15周期
a=i++; //movl -4(%ebp), %eax
//movl %eax, -8(%ebp)
//leal -4(%ebp), %eax
//incl (%eax)
总共: 11周期
a=i=i+1; //leal -4(%ebp), %eax
//incl (%eax)
//movl -4(%ebp), %eax
//movl %eax, -8(%ebp)
总共: 11周期

所以, 还要根据不同情况不同考虑

#6


同意mathe

#7


对于内部数据类型确实应该一样。

但对于用户自定义数据类型A:则按 ++A、A+=1、A++、A=A+1 的顺序递减。
道理与 ZhangYv(抵制日货就是阉割日本) 基本相同,
但我认为 A++ 低于 A+=1,因为前者需要临时变量,而如果该数据结构初始化比较复杂的话;
而 ++A 与 A+=1 孰高孰低,则看用户是否特殊化“++A”实现,还是简单的调用“ A+=1”实现的。

#8


自己看吧(Release下):

int i = rand();
00402407  call        rand (4062D8h) 
0040240C  mov         esi,eax 
++i;
0040240E  inc         esi  
cout << i;
0040240F  push        esi  
00402410  mov         ecx,offset std::cout (416210h) 
00402415  call        std::basic_ostream<char,std::char_traits<char> >::operator<< (4015E0h) 
i += 1;
0040241A  inc         esi  
cout << i;
0040241B  push        esi  
0040241C  mov         ecx,offset std::cout (416210h) 
00402421  call        std::basic_ostream<char,std::char_traits<char> >::operator<< (4015E0h) 
i = i + 1;
00402426  inc         esi  
cout << i;
00402427  push        esi  
00402428  mov         ecx,offset std::cout (416210h) 
0040242D  call        std::basic_ostream<char,std::char_traits<char> >::operator<< (4015E0h)

#9


然后再试一下吧 int i = rand() 改成 int i = 0 , 看看编译器会怎么做? :) 
编译器比你想象的聪明。

#10


再来看看类似这段新手爱写的程序有什么问题(这次编译器再聪明也帮不了你了):

char some[123] = "hello";
for( int i = 0; i < strlen(some); ++i )
{
cout << some[i];
}

#11


++i 最快
i++ 次之,多用一个临时变量
i+=1 第三,需要取地址
i = i+1 最后,并多用一个临时变量
同意上述观点。

#12


不同的编译器会有不同的结果
TC/VC/IntelC++编译器的结果均会不同
关键取决于编译器的优化能力
在不优化的情况下,++i和i++是相同的,速度最快,使用INC指令完成
i+=1和i=i+1是相同的,使用存储器寻址和寄存器加法完成

#13


i++ 快
少访内存

#14


显然与编译器的优化选项有关,
优化程度比较高的话都是一样的机器代码

#15


i++要快点

#16


up

#17


编译器会优化的

在算法分析里,我记得是说的完全等价。

#18


同意楼上的

这只是编译器考虑的问题。

在算法中,因该一样的

#19


IBM-PC汇编代码的长短其实说明不了问题
因为每条汇编指令的执行时间也不是定的
如果用MIPS指令写可能会好一点

#20


一群不懂编译的家伙在这瞎扯,笑死人了。

#21


怎样看每条语句运行需要多少周期?

#22


哈哈,涉及底层了!

#23


up

#24


i++    这个最快
i+=1    
i=i+1  这个最慢
看他们引用了几次地址就明白了

#25


To shenghuayi(oldman) :

看引用地址看不出什么来,我敢打赌现在常用的编译器在打开优化开关之后编译出来这三条指令是相同的,除非i不是整数而一个对象。

不同CPU之间也会有区另,如Intel支持单指令的自增一,而且支持直接对内存数据运算;而PPC则不行。

#26


学习

#27


标准C并未对i++; i+=1; i=i+1这些东西的实现方式作任何定义,而只是定义了相应表达式的功能.

你要问哪个快些,最好这样问:在XXXX CPU上,经XXXX编译器,用XXXX编译选项编译出来的目标
代码,哪个执行速度快?

这还不容易,把汇编拿出来看看不就知道了!

#1


没经证实的:
i++ : inc i

i+=1,i = i+1: 
      mov eax,i
      add eax,1
      mov i,eax

#2


好像一样

#3


++i 最快
i++ 次之,多用一个临时变量
i+=1 第三,需要取地址
i = i+1 最后,并多用一个临时变量

#4


等价,在编译器看来,代码都等价,没有区别

#5


以80386为例:

++i; // leal -4(%ebp), %eax
// incl (%eax)
i++;// leal -4(%ebp), %eax
// incl (%eax)
i=i+1;// leal -4(%ebp), %eax
// incl (%eax)
所以, 上面3个表达是一样.

换一下(leal: 2周期; movl: 4周期; incl: 1周期):
a=++i; //leal -4(%ebp), %eax
//incl (%eax)
//movl -4(%ebp), %eax
//movl %eax, -8(%ebp)
//movl -4(%ebp), %eax
总共: 15周期
a=i++; //movl -4(%ebp), %eax
//movl %eax, -8(%ebp)
//leal -4(%ebp), %eax
//incl (%eax)
总共: 11周期
a=i=i+1; //leal -4(%ebp), %eax
//incl (%eax)
//movl -4(%ebp), %eax
//movl %eax, -8(%ebp)
总共: 11周期

所以, 还要根据不同情况不同考虑

#6


同意mathe

#7


对于内部数据类型确实应该一样。

但对于用户自定义数据类型A:则按 ++A、A+=1、A++、A=A+1 的顺序递减。
道理与 ZhangYv(抵制日货就是阉割日本) 基本相同,
但我认为 A++ 低于 A+=1,因为前者需要临时变量,而如果该数据结构初始化比较复杂的话;
而 ++A 与 A+=1 孰高孰低,则看用户是否特殊化“++A”实现,还是简单的调用“ A+=1”实现的。

#8


自己看吧(Release下):

int i = rand();
00402407  call        rand (4062D8h) 
0040240C  mov         esi,eax 
++i;
0040240E  inc         esi  
cout << i;
0040240F  push        esi  
00402410  mov         ecx,offset std::cout (416210h) 
00402415  call        std::basic_ostream<char,std::char_traits<char> >::operator<< (4015E0h) 
i += 1;
0040241A  inc         esi  
cout << i;
0040241B  push        esi  
0040241C  mov         ecx,offset std::cout (416210h) 
00402421  call        std::basic_ostream<char,std::char_traits<char> >::operator<< (4015E0h) 
i = i + 1;
00402426  inc         esi  
cout << i;
00402427  push        esi  
00402428  mov         ecx,offset std::cout (416210h) 
0040242D  call        std::basic_ostream<char,std::char_traits<char> >::operator<< (4015E0h)

#9


然后再试一下吧 int i = rand() 改成 int i = 0 , 看看编译器会怎么做? :) 
编译器比你想象的聪明。

#10


再来看看类似这段新手爱写的程序有什么问题(这次编译器再聪明也帮不了你了):

char some[123] = "hello";
for( int i = 0; i < strlen(some); ++i )
{
cout << some[i];
}

#11


++i 最快
i++ 次之,多用一个临时变量
i+=1 第三,需要取地址
i = i+1 最后,并多用一个临时变量
同意上述观点。

#12


不同的编译器会有不同的结果
TC/VC/IntelC++编译器的结果均会不同
关键取决于编译器的优化能力
在不优化的情况下,++i和i++是相同的,速度最快,使用INC指令完成
i+=1和i=i+1是相同的,使用存储器寻址和寄存器加法完成

#13


i++ 快
少访内存

#14


显然与编译器的优化选项有关,
优化程度比较高的话都是一样的机器代码

#15


i++要快点

#16


up

#17


编译器会优化的

在算法分析里,我记得是说的完全等价。

#18


同意楼上的

这只是编译器考虑的问题。

在算法中,因该一样的

#19


IBM-PC汇编代码的长短其实说明不了问题
因为每条汇编指令的执行时间也不是定的
如果用MIPS指令写可能会好一点

#20


一群不懂编译的家伙在这瞎扯,笑死人了。

#21


怎样看每条语句运行需要多少周期?

#22


哈哈,涉及底层了!

#23


up

#24


i++    这个最快
i+=1    
i=i+1  这个最慢
看他们引用了几次地址就明白了

#25


To shenghuayi(oldman) :

看引用地址看不出什么来,我敢打赌现在常用的编译器在打开优化开关之后编译出来这三条指令是相同的,除非i不是整数而一个对象。

不同CPU之间也会有区另,如Intel支持单指令的自增一,而且支持直接对内存数据运算;而PPC则不行。

#26


学习

#27


标准C并未对i++; i+=1; i=i+1这些东西的实现方式作任何定义,而只是定义了相应表达式的功能.

你要问哪个快些,最好这样问:在XXXX CPU上,经XXXX编译器,用XXXX编译选项编译出来的目标
代码,哪个执行速度快?

这还不容易,把汇编拿出来看看不就知道了!