2017年3月

今天在写一个倒计时的时候,突然想起一个问题,“对于 js 的小数取整,那种方法效率最高呢?”

然后我就把我能想到的取整的方法做了一下测试,大概是这个样子

Math.floor(-100/3)
parseInt(-100/3)
~~(-100/3)
(-100/3 >> 0)
(-100/3 | 0)
( -100 - (-100%3) ) / 3

然后我把每种方法跑了 10^7 次,取了一下平均值,然后发现:

  • Math.floor 耗时 0.0000197 ms
  • parseInt 耗时 0.0000225 ms
  • ~~(-100/3)(-100/3 >> 0)(-100/3 | 0) 三个耗时基本相同,大概都是 0.0000029ms 的样子
  • ( -100 - (-100%3) ) / 3 耗时 0.0000155ms

基本可以看出,三个位运算的方法耗时最少,而且少很多,那么是不是我们就可以使用这三种方法了呢?

在说答案之前,我们先来看看他们都干了什么吧

首先,位运算为什么能取整?

因为 js 是弱类型的语言,在对一个数进行位运算的时候,实际上是先对其进行 ToInt32 操作,转换成整数,然后再进行位运算。那么这里就有一个问题,原来的数被 ToInt32 之后,会变成一个 32 位长的整数,多余的部分会被截掉,当然,还包含一个符号位,那么也就是说,我们实际有效的数字只有 31 位,也就是 2147483647-2147483648

所以,当你的数字超过这个范围的时候,使用位运算的时候,就会计算出一些很奇怪的数字,其实因为 ToInt32 的时候被截掉了

那么现在来看答案就比较明显了, 如果你的数字会超过 32 位,那么就不能使用位运算。

然后再来看看 Math.floor,它是向下取整,也就是说,如果你的数字是负数的话,向下取整就是这样

Math.floor(-1.5)   // -2

剩下的两个 parseInt(-100/3) 比较稳定,功能也强大,支持不同进制转换,但是耗时也最长。

( -100 - (-100%3) ) / 3 这一坨就不说了,速度还可以,但是不易维护,如果不是情况特殊的话,我应该不会用这种办法吧

最后,就看你的实际情况来选择喽~

今天就到这里啦,如果有什么不对的地方,请留言告诉我哈~

大家晚安~