我在网页上的<script>
标记内有以下代码,上面没有任何其他内容。我恐怕我现在没有上网。正如您所看到的,它以两种不同的方式将所有素数低于200万,并计算平均花费的时间。变量howOften
用于执行此操作多次,因此您可以对其进行平均。让我感到困惑的是,对于howOften == 1
,方法2更快,但对于howOften == 10
,方法1更快。即使你多次击中F5,这种差异也很显着。
我的问题很简单:怎么回事?
(这篇文章已被编辑,以纳入alf的建议。但这没有任何区别!我现在非常困惑。)
(再次编辑:howOften
等于或超过1000,时间似乎稳定.Alf的回答似乎是正确的。)
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);
答案 0 :(得分:2)
嗯,JS运行时是一个优化的JIT编译器。这意味着有一段时间,你的代码被解释(t int ),之后,它被编译(t jit ),最后你运行一个编译的代码(t <子>运行子>)。
现在你计算的很可能是(t int + t jit + t run )/ N.鉴于N上几乎线性依赖的唯一部分是t run ,不幸的是,这种比较没有多大意义。
所以答案是,我不知道。要有一个正确的答案,
更新:另请注意,在1个周期内,您的运行时间会低于系统计时器的分辨率,这意味着错误可能比您比较的实际值大。
答案 1 :(得分:0)
methodTwo只需要处理器执行较少的计算。在methodOne中,您的初始for循环正在执行maxN次。在methodTwo中,您的初始for循环正在执行(maxN -2)/ 2次。因此,在第二种方法中,处理器所执行的计算数量不到第一种方法的一半。事实上,每个方法都包含一个嵌套的for循环。所以methodOne的大O是maxN ^ 2。而方法二的大O是((maxN -2)/ 2)^ 2。