我们的问题是,在C语言中i++和++i的性能有区别吗?
c++的答案是什么?
我们的问题是,在C语言中i++和++i的性能有区别吗?
c++的答案是什么?
当前回答
i++有时比++ I快!
对于使用ILP(指令级并行)的x86架构,i++在某些情况下可能优于++i。
为什么?因为数据依赖关系。现代cpu可以并行化很多东西。如果接下来的几个CPU周期对i的增量值没有任何直接依赖,CPU可能会省略微码来延迟i的增量,并将其塞到“空闲插槽”中。这意味着您实际上得到了一个“免费”增量。
我不知道ILE在这种情况下走多远,但我认为如果迭代器变得太复杂,并做指针解引用,这可能不会工作。
下面是Andrei Alexandrescu对这个概念的解释:https://www.youtube.com/watch?v=vrfYLlR8X8k&list=WL&index=5
其他回答
[执行摘要:如果没有特定的理由使用i++,请使用++i。]
对于c++来说,答案有点复杂。
如果i是一个简单类型(不是c++类的实例),那么C给出的答案(“不,没有性能差异”)成立,因为编译器正在生成代码。
但是,如果i是c++类的实例,则i++和++i将调用其中一个操作符++函数。下面是这些函数的标准组合:
Foo& Foo::operator++() // called for ++i
{
this->data += 1;
return *this;
}
Foo Foo::operator++(int ignored_dummy_value) // called for i++
{
Foo tmp(*this); // variable "tmp" cannot be optimized away by the compiler
++(*this);
return tmp;
}
由于编译器不生成代码,而只是调用运算符++函数,因此没有办法优化掉tmp变量及其相关的复制构造函数。如果复制构造函数的开销很大,则会对性能产生重大影响。
即使在没有性能优势的内置类型上也应该使用++i的原因是为了给自己养成一个好习惯。
++i比i = i +1快,因为在i = i +1中发生了两个操作,第一个递增,第二次将其赋值给一个变量。但是在i++中只进行增量操作。
谷歌c++风格指南说:
Preincrement and Predecrement Use prefix form (++i) of the increment and decrement operators with iterators and other template objects. Definition: When a variable is incremented (++i or i++) or decremented (--i or i--) and the value of the expression is not used, one must decide whether to preincrement (decrement) or postincrement (decrement). Pros: When the return value is ignored, the "pre" form (++i) is never less efficient than the "post" form (i++), and is often more efficient. This is because post-increment (or decrement) requires a copy of i to be made, which is the value of the expression. If i is an iterator or other non-scalar type, copying i could be expensive. Since the two types of increment behave the same when the value is ignored, why not just always pre-increment? Cons: The tradition developed, in C, of using post-increment when the expression value is not used, especially in for loops. Some find post-increment easier to read, since the "subject" (i) precedes the "verb" (++), just like in English. Decision: For simple scalar (non-object) values there is no reason to prefer one form and we allow either. For iterators and other template types, use pre-increment.
两者都一样快;) 如果你想在处理器上进行相同的计算,只是计算的顺序不同。
例如,以下代码:
#include <stdio.h>
int main()
{
int a = 0;
a++;
int b = 0;
++b;
return 0;
}
生产以下组件:
0x0000000100000f24 <main+0>: push %rbp 0x0000000100000f25 <main+1>: mov %rsp,%rbp 0x0000000100000f28 <main+4>: movl $0x0,-0x4(%rbp) 0x0000000100000f2f <main+11>: incl -0x4(%rbp) 0x0000000100000f32 <main+14>: movl $0x0,-0x8(%rbp) 0x0000000100000f39 <main+21>: incl -0x8(%rbp) 0x0000000100000f3c <main+24>: mov $0x0,%eax 0x0000000100000f41 <main+29>: leaveq .日志含义 0x0000000100000f42 <main+30>: retq
你可以看到,对于a++和b++,它是一个包含助记符,所以它是相同的操作;)