【问题标题】:Does for(x = ...; x <= ...; x++) calculate ... in every loop in JavaScript?for(x = ...; x <= ...; x++) 是否在 JavaScript 的每个循环中计算 ...?
【发布时间】:2015-09-24 14:50:14
【问题描述】:

如果我写

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),使其非常慢?

或者它们是否相同且同样快?

【问题讨论】:

  • 这取决于编译器优化。
  • 一个考虑的例子:即使在单独的变量中声明数组的长度也有性能提升。

标签: javascript loops for-loop


【解决方案1】:

第一个表达式是初始值,不会重新计算。

显然,每次迭代都会评估条件,否则您将不知道何时完成。

条件表达式是否必须重新计算取决于表达式和JS实现及其JIT等。

【讨论】:

    【解决方案2】:

    当表达式涉及函数调用时,优化器不太可能相信函数的返回值是不变的并且函数没有副作用。所以是的,您的测试表达式可能会在每次迭代时重新评估。 (请注意,初始化表达式只会执行一次,因此将其移出循环头没有多大意义。)

    这种手工编码的优化是否值得取决于具体情况。如果您的循环经历了许多次迭代,那么这可能是值得的,但花一些时间研究需要更少迭代的替代方案可能是明智的。

    【讨论】:

      【解决方案3】:

      循环的每次迭代都会进行条件检查。

      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();
      

      现在,静态语句被移动到初始化部分,它只会在循环执行开始时被计算一次。

      【讨论】:

        【解决方案4】:

        不,不会评估 Math.Pow。看到这个:

        >function z(){console.log("test"); return 3;}
        <undefined
        
        >z()
        <3
        <test
        
        >var a = z();
        <undefined
        <test
        
        >a
        <3
        

        您可以从任何 Internet 浏览器控制台进行测试。如果每次都评估该函数,a 将打印test,但情况并非如此。


        对于第一种情况,每次都会重复:

        >for (var x = 1; x <= z(); x++)console.log("itt");
        <undefined
        <test
        <itt
        <test
        <itt
        <test
        <itt
        <test
        

        【讨论】:

        • 哦,你说的是第一个;你应该是明确的,因为有两个 Math.pow() 调用。至少我假设你说的只是第一个。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-03
        • 1970-01-01
        • 2017-04-28
        相关资源
        最近更新 更多