如果我写
for (var x = Math.pow(2, 2); x <= Math.pow(2, 12.345); i++) doSomething();
效率低于写作
var a = Math.pow(2, 2);
var b = Math.pow(2, 12.345);
for (var x = a; x <= b; x++) doSomething();
第一个示例是否会在每个循环中计算Math.pow(2,12.345),这会让它变得非常慢?
或者它们是否相同且速度相同?
答案 0 :(得分:3)
第一个表达式是初始值,不会重新计算。
显然,每次迭代都会评估条件,否则您将不知道何时完成。
是否必须重新计算条件表达式取决于表达式和JS实现及其JIT等。
答案 1 :(得分:2)
当表达式涉及函数调用时,优化器很可能不相信函数的返回值是不变的,并且函数没有副作用。所以是的,可能的情况是你的测试表达式将在每次迭代时重新评估。 (请注意,初始化表达式只会执行一次,因此将其移出循环标头并没有多大意义。)
这种手工编码的优化是否值得,取决于具体情况。如果你的循环经历了很多次迭代,那么它可能是值得的,但花一些时间研究一种需要更少迭代的替代方案可能是明智的。
答案 2 :(得分:1)
对循环的每次迭代进行条件检查。
for (var x = Math.pow(2, 2); x <= Math.pow(2, 12.345); i++) doSomething();
因此,每次都会调用Math.pow(..
来评估条件。因为循环的执行取决于条件。如果条件求值为true
,则继续执行循环,当条件求值为false
时,控件将被抛出/ break 循环。
此外,我还没有看到在循环条件中反复评估表达式的必要性,因为没有涉及其值在循环中更改的变量。
您的代码可以按照以下方式进行优化:
for (var x = Math.pow(2, 2), y = Math.pow(2, 12.345); x <= y; i++) doSomething();
现在,静态语句在初始化部分中移动,在循环执行开始时它只会被评估一次。
答案 3 :(得分:0)
不,不会评估Math.Pow。见:
>function z(){console.log("test"); return 3;}
<undefined
>z()
<3
<test
>var a = z();
<undefined
<test
>a
<3
您可以从任何互联网浏览器控制台进行测试。如果每次评估该功能,a
都会打印test
,但事实并非如此。
对于第一种情况,每次都会重复:
>for (var x = 1; x <= z(); x++)console.log("itt");
<undefined
<test
<itt
<test
<itt
<test
<itt
<test