JavaScript中的整数和小数运算速度

时间:2018-01-17 15:49:10

标签: javascript

这是我测试的代码。



    (function() {
        var i, x;
    
        console.time('a');
        for (i = x = 0; i < 1000000; x++) {
            if (x > 1000) {
                i++;
                x = 0;
            }
        }
        console.timeEnd('a');
    
        console.time('b');
        for (i = x = 0; i < 1000000; x += 0.001) {
            if (x > 1) {
                i++;
                x = 0;
            }
        }
        console.timeEnd('b');
    })();
        
    var i, x;
    
    console.time('c');
    for (i = x = 0; i < 1000000; x++) {
        if (x > 1000) {
            i++;
            x = 0;
        }
    }
    console.timeEnd('c');
    
    console.time('d');
    for (i = x = 0; i < 1000000; x += 0.001) {
        if (x > 1) {
            i++;
            x = 0;
        }
    }
    console.timeEnd('d');
&#13;
&#13;
&#13;

结果如下。 a是1200毫秒。 b是1200毫秒。 c是2300毫秒。 d是23000 ms。

a和b在操作速度上没有差别。 (即使你增加了操作次数)

,但..

c和d的运行速度是不同的10倍!!!

(a和c),(b和d)彼此是相同的代码。

不同之处在于a和b引用局部变量,c和d引用全局变量。

因此,可以理解根据搜索范围的速度差。

(a比c快,因为搜索范围更窄!)

但我无法理解整数与小数的运算速度的差异。

这就是为什么〜?

为什么&#39; a vs b&#39;没有速度差异,是否与d&#39;速度不同?

这个问题让我太累了。 请帮我。 T ^ T

我做了很多搜索来解决这个问题,但我无法解决它。 下面的链接是我看过的众多答案之一。

Why is accessing a variable using window.variable slower?

2 个答案:

答案 0 :(得分:0)

答案被其作者删除,所以我的评论。所以这就是我发现的:

修改

我纠正了我的愚蠢(我希望。@ Bergi会让我保持直率)。修改了实验,并在下面修改了评论。范围似乎是问题。使用全局范围的变量运行速度较慢,使用本地范围的变量运行速度更快。

结束修改

我认为问题在于通常在全局范围和/或范围层次结构中解析变量。

实验:

  • 在IIFE(&#34; a&#34;&amp;&#34; b&#34;)中发表评论var i,x声明
  • 转身&#34; d&#34;进入构造函数。实例化一个新对象。

Chrome中的结果:

  • &#34;&#34;似乎运行速度慢了约50%。
  • B&#34;跑得和原来一样慢#34; d&#34;
  • 作为对象&#34; d&#34;跑得快得多,5-8倍,球场。

注意:

  • 相对结果在Chrome vs. SO片段转轮

  • 中更具戏剧性
  • 原创&#34; d&#34; &安培;对象&#34; d&#34;在SO片段运行器中运行几乎相同。有趣。

&#13;
&#13;
    (function() {
       // var i, x;
    
        console.time('a');
        for (i = x = 0; i < 1000000; x++) {
            if (x > 1000) {
                i++;
                x = 0;
            }
        }
        console.timeEnd('a');
    
        console.time('b');
        for (i = x = 0; i < 1000000; x += 0.001) {
            if (x > 1) {
                i++;
                x = 0;
            }
        }
        console.timeEnd('b');
    })();
        
    var i, x;
    
    console.time('c');
    for (i = x = 0; i < 1000000; x++) {
        if (x > 1000) {
            i++;
            x = 0;
        }
    }
    console.timeEnd('c');
   
console.time('d');
for (i = x = 0; i < 1000000; x += 0.001) {
    if (x > 1) {
        i++;
        x = 0;
    }
}
console.timeEnd('d');     

function sloePoke() {
    this.q,
    this.r,
    this.go = function() {
    console.time('d');
    for (this.q = this.r = 0; this.q < 1000000; this.r += 0.001) {
        if (this.r > 1) {
            this.q++;
            this.r = 0;
        }
    }
    console.timeEnd('d');
    }
   }

var sloth = new sloePoke();
sloth.go();
&#13;
&#13;
&#13;

答案 1 :(得分:0)

很难确定确切的原因,但可以观察到一些事情。

首先,对于范围中的示例,可能会丢弃x,使此计算至少不具有意义。优化很容易看到x永远不会被使用,因此,无需对其进行评估。

至于第二个例子,十进制与整数不是造成差异的。例如,您可以尝试使用x+=7,并且您会有类似的延迟。

&#13;
&#13;
console.time('d');
for (i = 0, x = 0; i < 1000000000; x+=7 ) {
   
        i++;
       
};
console.timeEnd('d')
&#13;
&#13;
&#13;

如果初始x值更高,则相同:

&#13;
&#13;
console.time('d');
for (i = 0, x = 10000000000; i < 1000000000; x+=1 ) {
   
        i++;
       
};
console.timeEnd('d')
&#13;
&#13;
&#13;

使用数字,我们可以尝试找到引爆点。让我们使用Math.pow来尝试查找时间变化的位置。您会发现它在Math.pow(2, 30)Math.pow(2, 31)之间发生了巨大变化。尝试:

&#13;
&#13;
console.time('c');
for (i = 0, x = Math.pow(2, 30); i < 1000000000; x+=1 ) {
   
        i++;
       
};
console.timeEnd('c');

console.time('d');
for (i = 0, x = Math.pow(2, 31); i < 1000000000; x+=1 ) {
   
        i++;
       
};console.timeEnd('d')
&#13;
&#13;
&#13;

因此,由此可以通过single-precision formatdouble-precision format之间的差异来解释差异。 Math.pow(2,31)是单精度格式的限制(参见:https://en.wikipedia.org/wiki/Single-precision_floating-point_format)。虽然javascript Numbers被认为是双倍的,但没有什么可说的,引擎没有优化以便尽可能使用single-precision。 很高兴看到,当你向自己添加0.001时会发生什么。很快它就会提供需要双精度的东西。参见:

&#13;
&#13;
console.log(0.001 + 0.001 + 0.001 + 0.001 +0.001 + 0.001 + 0.001 + 0.001+0.001 + 0.001 + 0.001)
&#13;
&#13;
&#13;

同样,很难说这是确切的原因,但推动这种推理的一种方法是从Math.pow(2, 31) - 1000000000开始x(这意味着你将整个时间保持在单一的预设中)并增加并看看时间是如何演变的。让我们增加10000000,以便有一些重要的东西。这给了我这张表:

x starts at 1147483648: 2861s
x starts at 1157483648: 3100s
x starts at 1167483648: 3537s
x starts at 1177483648: 3366s
x starts at 1187483648: 3656s
x starts at 1197483648: 3916s
x starts at 1207483648: 4257s
x starts at 1217483648: 4537s
x starts at 1227483648: 4587s
x starts at 1237483648: 4798s
x starts at 1247483648: 4910s
x starts at 1257483648  5200s
x starts at 1267483648: 5364s

这似乎或多或少线性增加。如果你尝试递减,你会发现时间没有变化(当然这也取决于其他事情,但一般来说这至少取决于我的结果)。

因此,基于此,您的示例中的时间差异似乎基于使用单精度的javascript引擎,这可以加速计算。