我想知道如何针对资源非常有限的系统优化循环。比方说,如果我们有一个基本的for
循环,就像(用javascript
编写):
for(var i = someArr.length - 1; i > -1; i--)
{
someArr[i]
}
老实说,我不知道,!=
不比>
便宜吗?
我将非常感谢任何涵盖基本运算符背景下的计算成本的资源,例如前面提到的>>
,~
,!
等。
答案 0 :(得分:16)
现代CPU的性能远非微不足道。以下是一些使其复杂化的事情:
所以简短的回答是“不要试图超越编译器”。如果您能够在两个等效表达式之间进行选择,则编译器可能会执行相同的操作,并将选择最有效的表达式。根据所有上述因素,指令的成本会有所不同。执行哪些其他指令,CPU缓存中有哪些数据,运行代码的精确CPU模型等等。在一种情况下超高效的代码在其他情况下可能效率非常低。编译器将尝试选择最普遍有效的指令,并尽可能安排它们。除非你比编译器了解更多,否则你不太可能做得更好。
除非你真的知道你在做什么,否则不要尝试这样的微观优化。如上所示,低级性能是一个非常复杂的主题,并且很容易编写导致远较慢的代码的“优化”。或者只是牺牲对可以完全没有区别的东西的可读性。
此外,您的大多数代码根本不会对性能产生可衡量的影响。 人们通常喜欢在这个问题上引用(或错误引用)Knuth:
我们应该忘记小的效率,比如大约97%的时间:过早的优化是所有邪恶的根源
人们经常将此解释为“不要试图优化代码”。如果你真的阅读了完整的引用,一些更有趣的后果应该变得清晰:
大部分时间,我们应该忘记微优化。大多数代码执行得很少,优化无关紧要。记住CPU每秒可以执行的指令数量,显然必须执行非常的代码块,以便对其进行优化以产生任何影响。因此,大约97%的时间,您的优化将浪费时间。但他也说有时(3%的时间),你的优化将重要。显然,寻找那些3%有点像在大海捞针。如果您只是决定“优化代码”,那么您将浪费时间在前97%。相反,您需要首先找到实际需要优化的3%。换句话说,通过分析器运行代码,让它告诉你哪个代码占用了最多的CPU时间。然后你知道在哪里优化。然后你的优化不再为时过早。
答案 1 :(得分:10)
在极端(实时嵌入式系统?)情况下,这种微优化会对您的代码产生显着差异的可能性极小。如果担心让代码可读和可维护,那么你的时间可能会更好。
如有疑问,请先问唐纳德克努特:
http://shreevatsa.wordpress.com/2008/05/16/premature-optimization-is-the-root-of-all-evil/
或者,对于微观优化的略微不那么高的看法:
答案 2 :(得分:1)
大多数比较具有相同的滑行,因为处理器只是在所有方面进行比较,然后在此之后根据此前比较产生的标志做出决定,因此比较信号根本不重要。但是一些架构试图根据你所比较的价值来加速这个过程,比如0的比较。
据我所知,按位运算是最便宜的运算,比加法和减法略快。乘法和除法运算有点贵,而且比较是沿海运营的最高点。
答案 3 :(得分:1)
这就像要求一条鱼,当我宁愿教你钓鱼时。
有很简单的方法可以了解自己需要多长时间。我最喜欢的是只复制代码10次,然后将其包装在10 ^ 8次的循环中。如果我运行它并查看我的手表,它所需的秒数就会转换为纳秒。
说不做过早优化是“不要”。如果你想要“做到”,你可以尝试一种主动的性能调整技术,如this。
BTW我最喜欢的循环编码方式是:
for (i = N; --i >= 0;){...}
答案 4 :(得分:0)
过早优化可能是危险的,最好的方法是编写应用程序而不用担心,然后找到慢点并优化它们。如果你真的担心这个使用较低级别的语言。与像C这样的低级语言相比,像javascript这样的解释性语言会花费你一些处理能力。
答案 5 :(得分:0)
在这种特殊情况下,> vs =可能不是性能问题。然而,>通常是更安全的选择,因为可以防止修改代码的情况流入杂草并陷入无限循环。