我尝试对“++”,“+=1”和“+=10000”分别执行10亿次操作。奇怪的是,时钟周期的数量(根据time.h)实际上与直觉相反。人们可能会认为任何最快的都是“++”,然后是“+=1”,然后是“+=10000”,但数据显示出轻微的相反趋势。这种差异在执行10亿个操作时更加明显。这一切都是针对整数的。
我正在涉足科学计算,所以我想测试操作符的性能。例如,如果其中任何一个操作符的操作时间与输入成线性关系。
++i
还是 i+=1
都无所谓。我们都知道这一点。但是提问者不知道。这就是他为什么要问的原因。我知道,当我编程时能够忽略这样的性能问题的唯一原因是因为我已经具备了必要的知识来确定“这并不重要”。所以,对于提问者来说,这确实很重要。他需要一些答案来停止担心。 - jalf不,不,是的*,是的*,分别。
*但你真的在意吗?
编辑:为了给出一些现代处理器的概念,你可能可以在进行一次内存访问的时间内完成200个整数加法,而只有50个整数乘法。如果你仔细想想,你大部分时间仍然会受到内存访问的限制。
++i
比i += 1
快?它们做的是完全相同的事情?有时,添加常量或变量可能会有所不同,但在这种情况下,您在两种情况下都加了一个常量。 ++
比 +=
快”(除此之外,这些简单的经验法则几乎从来都不正确,至少不是在所有情况下)。关于您的评估,这里来个小技巧:试试 循环展开。 循环展开是重复在循环中相同语句以减少循环迭代次数。
大多数现代处理器都不喜欢分支指令。 处理器有一个预取指令队列,可以加速处理。 他们真的不喜欢分支指令,因为处理器必须在分支之后清空队列并重新加载。 这比仅处理连续指令需要更多时间。
编码处理时间时,请尽量减少分支数量,这可能发生在循环结构和决策结构中。
根据架构不同,整数算术的内置运算符直接转换为汇编代码(据我所知),++、+=1和+=10000的速度可能是相等的;乘法的速度则取决于平台,重载运算符的速度取决于您自己。
C++运算符引起的性能问题并不是来自于运算符本身,也不是来自于运算符的实现。它来自于语法,来自于在你不知道的情况下运行的隐藏代码。
最好的例子是,在一个已经实现了operator[]的对象上实现快速排序,但内部却使用了链表。现在,你将得到O(n^2logn)而不是O(nlogn)[1]。
性能问题的问题在于你无法确切地知道你的代码最终会变成什么样子。
[1]我知道快速排序实际上是O(n^2),但它很少达到这个级别,平均分布将给你O(nlogn)。
唐纳德·克努斯:“我们应该忘记小的效率问题,大约有97%的时间:过早优化是万恶之源”
除非你正在编写极其时间关键的软件,否则你可能应该担心其他事情。
简短回答:在测量之前应该打开优化。
长答案:如果您已经打开了优化,正在对整数执行操作,但仍然得到 ++i;
和 i + = 1;
的不同时间,则可能是时候获得更好的编译器了 - 这两个语句具有完全相同的语义,一个称职的编译器应将它们转换为相同的指令序列。
y = x++;
和y = (x += 1);
不是 等价的。y = (x += 1);
的意思是y = ++x;
。 - Steve Schnepp