Javascript - 如何使这个 pi 计算算法运行得更快?

the*_*714 1 javascript algorithm math pi numbers

该算法的工作原理:它首先生成一个点的随机坐标。然后它找到每个点到圆中心的距离。如果距离<=1,则该点在圆内,否则在圆外。圆内点数与总点数之比接近pi。

我想让这个算法运行得更快。我该怎么做?

function calc(iterations) {
    pointCircle = 0, total = 0, x = 0, y = 0, distance = 0, pi = 0;
    for (let i = 0; i < iterations; i++) {
        x = Math.random().toFixed(1);
        y = Math.random().toFixed(1);
        distance = Math.sqrt(x * x + y * y);
        if (distance <= 1) {pointCircle++;}total++;
    }
    pi = 4 * (pointCircle / total); console.log(pi);
}
Run Code Online (Sandbox Code Playgroud)

Cer*_*nce 7

.toFixed(1)使得计算更加不准确,并且消耗大量 CPU 时间,至少在 V8 上是这样。去掉它,给定数量的(大)迭代所需的时间似乎会下降约 8 倍。

// Original code
function calc(iterations) {
    pointCircle = 0, total = 0, x = 0, y = 0, distance = 0, pi = 0;
    for (let i = 0; i < iterations; i++) {
        x = Math.random().toFixed(1);
        y = Math.random().toFixed(1);
        distance = Math.sqrt(x * x + y * y);
        if (distance <= 1) {pointCircle++;}total++;
    }
    pi = 4 * (pointCircle / total); console.log('pi', pi);
}
setTimeout(() => {
  const t0 = performance.now();
  calc(1000000)
  console.log('time', performance.now() - t0);
}, 2000);
Run Code Online (Sandbox Code Playgroud)

// Modified code
function calc(iterations) {
    pointCircle = 0, total = 0, x = 0, y = 0, distance = 0, pi = 0;
    for (let i = 0; i < iterations; i++) {
        x = Math.random();
        y = Math.random();
        distance = Math.sqrt(x * x + y * y);
        if (distance <= 1) {pointCircle++;}total++;
    }
    pi = 4 * (pointCircle / total); console.log('pi', pi);
}
setTimeout(() => {
  const t0 = performance.now();
  calc(1000000)
  console.log('time', performance.now() - t0);
}, 2000);
Run Code Online (Sandbox Code Playgroud)

另一个改进可以通过正确确定变量的范围来实现,而不是重新分配对象的属性window,这看起来可以将 V8 上的速度进一步提高大约 3 倍。

// Modified code 2
function calc(iterations) {
    let total = 0;
    let pointCircle = 0;
    for (let i = 0; i < iterations; i++) {
        const x = Math.random();
        const y = Math.random();
        if (Math.sqrt(x * x + y * y) <= 1) { pointCircle++; }
        total++;
    }
    const pi = 4 * (pointCircle / total); console.log('pi', pi);
}
setTimeout(() => {
  const t0 = performance.now();
  calc(1000000)
  console.log('time', performance.now() - t0);
}, 2000);
Run Code Online (Sandbox Code Playgroud)

谢谢btillyMath.sqrt也不需要。

毕竟,当且仅当原始数字小于 1 时,sqrt 才小于 1。

这会减少一点。

// Modified code 2
function calc(iterations) {
    let total = 0;
    let pointCircle = 0;
    for (let i = 0; i < iterations; i++) {
        const x = Math.random();
        const y = Math.random();
        if (x * x + y * y <= 1) { pointCircle++; }
        total++;
    }
    const pi = 4 * (pointCircle / total); console.log('pi', pi);
}
setTimeout(() => {
  const t0 = performance.now();
  calc(1000000)
  console.log('time', performance.now() - t0);
}, 2000);
Run Code Online (Sandbox Code Playgroud)

  • 您应该能够通过删除“Match.sqrt”来再次加快速度。毕竟,当且仅当原始数字小于 1 时,`sqrt` 才小于 1。 (4认同)