我在 <script>
中有以下代码网页上没有其他内容的标签。恐怕我目前还没有在线。正如您所看到的,它以两种不同的方式将 200 万以下的所有素数相加,并计算平均花费的时间。变量howOften
用于多次执行此操作,以便您可以对其进行平均。让我困惑的是,对于howOften == 1
,方法2更快,但是对于howOften == 10
,方法1是。差异非常显着,即使您按 F5 几次,差异仍然存在。
我的问题很简单:怎么会?
(这篇文章已被编辑以纳入阿尔夫的建议。但这没有什么区别!我现在非常困惑。)
(再次编辑:当 howOften
等于或超过 1000 时,时间看起来很稳定。阿尔夫的答案似乎是正确的。)
function methodOne(maxN) {
var sum, primes_inv, i, j;
sum = 0;
primes_inv = [];
for ( var i = 2; i < maxN; ++i ) {
if ( primes_inv[i] == undefined ) {
sum += i;
for ( var j = i; j < maxN; j += i ) {
primes_inv[j] = true;
}
}
}
return sum;
}
function methodTwo(maxN) {
var i, j, p, sum, ps, n;
n = ((maxN - 2) / 2);
sum = n * (n + 2);
ps = [];
for(i = 1; i <= n; i++) {
for(j = i; j <= n; j++) {
p = i + j + 2 * i * j;
if(p <= n) {
if(ps[p] == undefined) {
sum -= p * 2 + 1;
ps[p] = true;
}
}
else {
break;
}
}
}
return sum + 2;
}
// ---------- parameters
var howOften = 10;
var maxN = 10000;
console.log('iterations: ', howOften);
console.log('maxN: ', maxN);
// ---------- dry runs for warm-up
for( i = 0; i < 1000; i++ ) {
sum = methodOne(maxN);
sum = methodTwo(maxN);
}
// ---------- method one
var start = (new Date).getTime();
for( i = 0; i < howOften; i++ )
sum = methodOne(maxN);
var stop = (new Date).getTime();
console.log('methodOne: ', (stop - start) / howOften);
// ---------- method two
for( i = 0; i < howOften; i++ )
sum = methodTwo(maxN);
var stop2 = (new Date).getTime();
console.log('methodTwo: ', (stop2 - stop) / howOften);
最佳答案
嗯,JS运行时是一个优化的JIT编译器。这意味着,您的代码有一段时间会被解释 (tint),之后会被编译 (tjit),最后运行编译后的代码 (t 运行)。
现在您计算出的最有可能是 (tint+tjit+trun)/N。鉴于唯一几乎线性依赖于 N 的部分是 trun,不幸的是,这种比较没有多大意义。
所以答案是,我不知道。为了得到正确的答案,
- 将您尝试分析的代码提取到函数中
- 对这些函数运行预热周期,并且不要使用预热周期中的计时
- 运行超过 1..10 次,包括热身和测量
- 尝试交换算法测量时间的顺序
- 如果可以的话,深入了解 JS 解释器的内部结构,并确保您了解发生的情况:您真的衡量了您认为自己所做的事情吗? JIT 是否在预热周期期间运行,而不是在测量时运行?等等等等
更新:另请注意,对于 1 个周期,您获得的运行时间小于系统计时器的分辨率,这意味着错误可能大于您比较的实际值。
关于javascript - 相同的代码如果执行得更频繁,需要的时间会更长?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8862359/