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

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

本文关键字:10000 floor vs toFixed Performance Math      更新时间:2024-03-30

我需要将两个浮点值比较到一定的精度(即小数点后4位):

var float1 = 0.0025132741228718345;
var float2 = 0.0025132812393818293;

我看到的两个选项:

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

或:

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

由于手术每秒会发生60次,我问自己:

  1. 哪个选项的性能更高
  2. 其中一个选项被广泛接受吗
  3. 还有第三种选择吗
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(基于Chromium的浏览器)

  • 地板:204.911毫秒
  • 至固定时间:4145.529毫秒
  • 减法:292.390毫秒

SpiderMonkey(基于Firefox的浏览器)

  • 楼层:566.81ms
  • 至固定时间:683.56ms
  • 减法:423.76ms

在您给出的两个选项中,Math.floor方法是速度更快的一个。

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

(如果你不相信我的话,你自己运行这个基准测试。)

快速版本:

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

基准标记:在此处输入链接描述

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

它似乎是基于round函数的toFixed,所以最好使用它来代替