关于javascript:性能:toFixed()与Math.floor(x * 10000)

Performance: toFixed() vs. Math.floor(x * 10000)

我需要比较两个浮点值到某个精度(即4个小数位):

1
2
var float1 = 0.0025132741228718345;
var float2 = 0.0025132812393818293;

我看到两个选项:

1
Math.floor(float1 * 10000) === Math.floor(float2 * 10000); // 25 === 25

...要么:

1
float1.toFixed(4) === float2.toFixed(4) //"0.0025" ==="0.0025"

由于操作将每秒发生60次,所以我问自己:

  • 哪个选项具有更高的性能?
  • 是更广泛接受的选择之一吗?
  • 还有第三种选择吗?

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    function floor(f1, f2) {
        return Math.floor(f1 * 10000) === Math.floor(f2 * 10000);
    }
    function toFixed(f1, f2) {
        return f1.toFixed(4) === f2.toFixed(4);
    }
    function subtract(f1, f2) {
        return Math.abs(f1 - f2) < 0.00001;
    }
    function test(fn) {
         console.time(fn.name);
         for (let i = 0; i < 1000000; ++i) {
             fn(Math.random(), Math.random());
         }
         console.timeEnd(fn.name);
    }
    for (const fn of [floor, toFixed, subtract]) {
        test(fn);
    }

    引擎基准

    v8(基于铬的浏览器)

    • 地板:204.911毫秒
    • 固定:4145.529 ms
    • 减:292.390毫秒

    SpiderMonkey(基于Firefox的浏览器)

    • 地板:566.81ms
    • 固定:683.56ms
    • 减:423.76ms

    在您提供的两个选项之间,Math.floor方法是最快的方法。

    不过,选择subtract可能是一个明智的选择。

    (如果您不相信我,请自己运行此基准。)


    1
    2
    Math.round(142.89 * 100) / 100 // 142.89
    Math.floor(142.89 * 100) / 100 // 142.88

    看来toFixed是基于round函数的,所以最好改用它


    快速版本:

    1
    2
    3
    function FastFloor(f1, f2) {
      return ~~(f1 * 10000) === ~~(f2 * 10000);
    }

    基准测试:
    在此处输入链接说明