Javascript 性能:toFixed()与数学地板(x*10000)
我需要将两个浮点值比较到某个精度(即小数点后4位): 我看到的两个选择:Javascript 性能:toFixed()与数学地板(x*10000),javascript,Javascript,我需要将两个浮点值比较到某个精度(即小数点后4位): 我看到的两个选择: Math.floor(float1 * 10000) === Math.floor(float2 * 10000); // 25 === 25 …或: float1.toFixed(4) === float2.toFixed(4) // "0.0025" === "0.0025" 因为手术每秒会发生60次,我问自己: 哪些选项具有更高的性能 其中一种选择是否更被广泛接受 还有第三种选择吗 功能楼层(一层、二层){ 返回
Math.floor(float1 * 10000) === Math.floor(float2 * 10000); // 25 === 25
…或:
float1.toFixed(4) === float2.toFixed(4) // "0.0025" === "0.0025"
因为手术每秒会发生60次,我问自己:
功能楼层(一层、二层){
返回数学楼层(f1*10000)==数学楼层(f2*10000);
}
固定功能(f1、f2){
返回f1.toFixed(4)==f2.toFixed(4);
}
函数减法(f1,f2){
返回数学绝对值(f1-f2)<0.00001;
}
功能测试(fn){
控制台时间(fn.名称);
对于(设i=0;i<1000000;++i){
fn(Math.random(),Math.random());
}
console.timeEnd(fn.name);
}
for(常数fn of[floor,toFixed,subtract]){
试验(fn);
}
发动机基准
v8(基于Chromium的浏览器)
- 楼层:204.911 ms
- 固定时间:4145.529毫秒
- 减去:292.390毫秒
- 楼层:566.81毫秒
- 固定时间:683.56毫秒
- 减去:423.76ms
Math.floor
方法速度更快
不过,选择减法可能是明智的选择
(如果您不相信我,请自己运行此基准测试。)
它似乎是基于round函数的toFixed,因此最好使用它来代替快速版本:
功能快速楼层(f1、f2){
返回~~(f1*10000)==~(f2*10000);
}
第三个选项是abs(float1-float2),非常感谢!为什么选择substract
可能是明智的选择?因为subtract
的结果在我测试过的两个引擎中的算术平均值最低,与所有其他实现相比(注意floor
在基于Firefox的浏览器上不是最快的)。@kraftwer1 With floor,0.00250等于0.00259,但不等于0.00249,尽管0.00249更接近于0.00250。这就是你可能应该选择的原因(在这个答案中把fred改为“subtract”)(这个问题的另一个典型名称是“fuzzy equals”。)我也更喜欢subtract()
。它基于两个数字之间的距离。备选方案将数字划分为若干类。因此,对于非常接近的数字(例如差1e-10),结果可能为假,但差1e-6变为真。
float1.toFixed(4) === float2.toFixed(4) // "0.0025" === "0.0025"
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);
}
Math.round(142.89 * 100) / 100 // 142.89
Math.floor(142.89 * 100) / 100 // 142.88