我通常不喜欢微基准测试,但这个测试结果非常有趣。
http://ernestdelgado.com/archive/benchmark-on-the-floor/
它表明,在Javascript中计算floor时,Math.floor
是最慢的。而~~n
、n|n
、n&n
都更快。
这似乎很惊人,因为我期望在今天的现代浏览器中实现JavaScript的人应该是相当聪明的人。
Math.floor
是否执行其他方法无法完成的重要操作?使用它是否有任何理由?
我通常不喜欢微基准测试,但这个测试结果非常有趣。
http://ernestdelgado.com/archive/benchmark-on-the-floor/
它表明,在Javascript中计算floor时,Math.floor
是最慢的。而~~n
、n|n
、n&n
都更快。
这似乎很惊人,因为我期望在今天的现代浏览器中实现JavaScript的人应该是相当聪明的人。
Math.floor
是否执行其他方法无法完成的重要操作?使用它是否有任何理由?
Math.floor
较慢(在一些测试中它更快)是因为它涉及到函数调用。旧版JavaScript实现不能内联函数调用。更新的引擎可以内联调用,或者至少使属性查找更快,但它们仍然需要一个保护条件以防您(或其他脚本)覆盖了Math.floor
函数。然而,开销很小,因此速度差异不大。
更重要的是,正如几条评论中提到的那样,其他方法并不等价。它们都通过位运算来工作。位运算符通过截断数字自动将其操作数转换为32位整数。如果数字适合32位,则没有问题,但JavaScript数字是64位浮点数,可能比2147483647大得多。
它们还会针对负数给出不同的结果,因为将其转换为整数会截断,而Math.floor
总是向下舍入。例如,Math.floor(-2.1) === -3
,但(-2.1)|(-2.1) === -2
。
如果您知道自己只处理小于2147483648的正数,并且需要在旧版浏览器中从代码中挤出每一位性能(首先确保它确实是瓶颈。它可能不是。),我会使用更简单的方法:x|0
。它不会评估两次变量,即使x
是一个表达式也可以工作(只需确保将其置于括号中,以避免运算优先级问题)。这与现代浏览器无关,与实施ECMA标准有关。 即使有更快的方法,您也不能只改变某个函数的执行方式。 这可能会破坏现有的代码。
Math.Floor必须考虑处理不同类型的许多不同情况。 他们是否可以通过采取您所描述的捷径来使不同的场景更快? 也许他们可以,但那可能会破坏其他场景。 表面上看起来很小的东西,下面可能有一座冰山。
Math.floor("foo")
返回 NaN
。但如果这是唯一的好处,我会尝试使用另一种方法。至少在 JavaScript 支持整数除法之前是这样的。 - Mark BolusmjakMath.floor()
可以正确地将负数向下舍入,而大多数位运算符则向0舍入(尽管>>>
完全超出了范围)。 - Ted Hopp
~~n
,n|n
和n&n
的结果与Math.floor
不同。前三个只能返回32位的整数。试试将n
设置为50000000000.4
。 - kennytmMath.floor
是最快的。 - Justin JohnsonMath.floor
不同 - 它们与Math.trunc
相同,对于负非整数有所不同。 - Grumdrig