我有以下JavaScript函数来计算素数的数量< = n
:
function F(n) {
var i = 0, a = 3, b = 1, p = [2], s = 2, l = 0;
while (a <= n) {
s = p[i];
if (a % s) {
if (b < s || i === l) {
p[++l] = a;
} else {
++i;
continue;
}
}
b = Math.sqrt(a += 2) | 0;
i = 0;
}
return l + 1 - (n < 2);
}
这当前有效,并且当在节点5.5中运行时,它可以在大约29.9秒内计算小于10 ^ 8的素数。我想优化它,我想到的一件事就是预先分配数组长度。但是,我尝试过的所有方法都只增加了运行时间。
我尝试的一件事是将p.length
设置为我要处理的素数的近似数。我在var
声明行下面添加了以下行:
p.length = n / (Math.log(n) - 1) | 0
但是这使得10 ^ 8的运行时间增加了1.5秒。我也尝试将数组声明更改为new Array(n / (Math.log(n) - 1) | 0)
,甚至尝试使用一些新类型的数组,如new Uint32Array(n / (Math.log(n) - 1) | 0)
),但无济于事。
JSPerf tests似乎表明应该会有显着的性能提升,但我只是看到了损失。我有什么遗失的吗?