你会写数字千分位格式化,那你比较过它们的性能吗?

478 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第15天,点击查看活动详情

打破枷锁,勇往直前,一起加油!

相信大家都曾经处理过数字千分位格式化,大家也一定知道不只一种方法,那么你比较过哪种方式的性能最好,耗时最小吗?

在我的了解中,有四种主流的方案:分别是利用正则、转换为数组、字符串拆分和toLocaleString()。下面的方案只处理正整数

方案一:toLocaleString()

这是最简单的办法

(123456789).toLocaleString() //'123,456,789'

方案二: 利用正则

String(123456789).replace(/\d{1,3}(?=(\d{3})+(\.|$))/g,'$&,')//'123,456,789'

方案三: 转换数组

function format1(n: number): string{
  let str: string = '';
  n = Math.floor(n)
  const arr = n.toString().split('').reverse();
  const length = arr.length;
  for(let i = 0; i < length; i++){
    if(i % 3 == 0 && i != length - 1){
      str += arr[i] + ','
    }else{
      str += arr[i]
    }
  }
  console.log(arr)
  return str;
}

console.log(format1(1234567891))//'1,987,654,321'

方案四: 字符串拆分

function format2(n :number): string{
  n = Math.floor(n) // 只考虑整数
  
  let str = '';
  let strN = n.toString();
  let length = strN.length;

  for(let i = length - 1; i >= 0; i--){
    let j = length - i;
    if(j % 3 == 0){
      str = ',' + strN[i] + str
    }else{
      str = strN[i] + str
    }
  }

  return str

}

console.log(format2(1234567891))//'1,987,654,321'

在上面基本的4种方案都可以实现数字千分位格式化,肯定还会存在其他的实现方式,但依然是这几种方式的延伸。

性能分析

console.time('toLocaleString')
for(let i = 0; i < 10 * 10000; i++){
  (1234567891).toLocaleString()
}
console.timeEnd('toLocaleString')//toLocaleString: 65.544677734375 ms

console.time('reg')
for(let i = 0; i < 10 * 10000; i++){
  String(1234567891).replace(/\d{1,3}(?=(\d{3})+(\.|$))/g,'$&,')
}
console.timeEnd('reg')//reg: 49.72509765625 ms

console.time('format1')
for(let i = 0; i < 10 * 10000; i++){
  format1(1234567891)
}
console.timeEnd('format1')//format1: 28.423095703125 ms


console.time('format2')
for(let i = 0; i < 10 * 10000; i++){
  format2(1234567891)
}
console.timeEnd('format2')//format2: 21.998046875 ms

通过上方对代码运行时间的测试,并结合自己在本地运行多次的出如下运行时间结果 format2 < format1 < reg <toLocaleString;

结论

  1. 正则相对还是比较耗费性能的
  2. 结合上一篇文章得出计算机对字符串的处理要优于计算机对数组的处理,尤其是当数组的处理大量使用数组内置方法的时候。
  3. 还是要熟悉基础api的使用,大部分人想到的数字千分位格式化的处理是使用函数或数组,甚至去找个库来使用,难道toLocaleString不香吗,当然在处理大量数据的时候尽量少使用内置api,其比较耗费时间,但在实际工作中处理几个,几十个甚至几百个数据还是不错的。
  4. 做性能测试尽量使用大量数据,10万加吧。否则得到的数据可能不太准确,就行这里最开始使用10次循环,reg对应的运行时间十分不稳定,toLocaleString的耗时最短的,还是需要大量数据进行测试,数据会相对更加稳定。