这是我测试的代码。
(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;
结果如下。 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
我做了很多搜索来解决这个问题,但我无法解决它。 下面的链接是我看过的众多答案之一。
答案 0 :(得分:0)
答案被其作者删除,所以我的评论。所以这就是我发现的:
修改
我纠正了我的愚蠢(我希望。@ Bergi会让我保持直率)。修改了实验,并在下面修改了评论。范围似乎是问题。使用全局范围的变量运行速度较慢,使用本地范围的变量运行速度更快。
结束修改
我认为问题在于通常在全局范围和/或范围层次结构中解析变量。
实验:
var i,x
声明Chrome中的结果:
注意:
相对结果在Chrome vs. SO片段转轮
原创&#34; d&#34; &安培;对象&#34; d&#34;在SO片段运行器中运行几乎相同。有趣。
(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;
答案 1 :(得分:0)
很难确定确切的原因,但可以观察到一些事情。
首先,对于范围中的示例,可能会丢弃x
,使此计算至少不具有意义。优化很容易看到x
永远不会被使用,因此,无需对其进行评估。
至于第二个例子,十进制与整数不是造成差异的。例如,您可以尝试使用x+=7
,并且您会有类似的延迟。
console.time('d');
for (i = 0, x = 0; i < 1000000000; x+=7 ) {
i++;
};
console.timeEnd('d')
&#13;
如果初始x值更高,则相同:
console.time('d');
for (i = 0, x = 10000000000; i < 1000000000; x+=1 ) {
i++;
};
console.timeEnd('d')
&#13;
使用数字,我们可以尝试找到引爆点。让我们使用Math.pow
来尝试查找时间变化的位置。您会发现它在Math.pow(2, 30)
和Math.pow(2, 31)
之间发生了巨大变化。尝试:
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;
因此,由此可以通过single-precision format
与double-precision format
之间的差异来解释差异。 Math.pow(2,31)是单精度格式的限制(参见:https://en.wikipedia.org/wiki/Single-precision_floating-point_format)。虽然javascript Numbers
被认为是双倍的,但没有什么可说的,引擎没有优化以便尽可能使用single-precision
。
很高兴看到,当你向自己添加0.001时会发生什么。很快它就会提供需要双精度的东西。参见:
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;
同样,很难说这是确切的原因,但推动这种推理的一种方法是从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引擎,这可以加速计算。