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
在您提供的两个选项之间,
不过,选择
(如果您不相信我,请自己运行此基准。)
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); } |
基准测试:
在此处输入链接说明