truncar round redondear quitar hacia decimales arriba javascript optimization

round - quitar decimales javascript



¿Por qué JavaScript Math.floor es la forma más lenta de calcular floor en Javascript? (2)

Por lo general, no soy partidario de microbenchmarks. Pero este tiene un resultado muy interesante.
http://ernestdelgado.com/archive/benchmark-on-the-floor/

Sugiere que Math.floor es la forma MÁS LENTA de calcular el piso en Javascript. ~~n , n|n , n&n todo es más rápido.
Esto parece bastante impactante, ya que supongo que las personas que implementan Javascript en los navegadores modernos de hoy serían personas bastante inteligentes.

¿El piso hace algo importante que los otros métodos no hacen? ¿Hay alguna razón para usarlo?


La razón principal por la que Math.floor es más lento (en realidad, en algunas pruebas que he hecho es más rápido) es que implica una llamada a una función. Las implementaciones más antiguas de JavaScript no podían hacer llamadas a funciones en línea. Los motores más nuevos pueden alinear la llamada, o al menos hacer que la búsqueda de propiedades sea más rápida, pero aún necesitan una condición de protección en caso de que usted (o algún otro script) Math.floor función Math.floor . Sin embargo, la sobrecarga es mínima, por lo que no hay mucha diferencia en la velocidad.

Sin embargo, más importante aún, como se mencionó en varios comentarios, los otros métodos no son equivalentes . Todos trabajan haciendo operaciones bit a bit. Los operadores bit a bit convierten automáticamente sus operandos a enteros de 32 bits truncando el número. Eso está bien si el número cabe en 32 bits, pero los números de JavaScript son flotantes de 64 bits, que podrían ser mucho más grandes que 2147483647.

También dan un resultado diferente para números negativos, ya que la conversión a enteros se trunca y Math.floor siempre redondea hacia abajo. Por ejemplo, Math.floor(-2.1) === -3 , pero (-2.1) | (-2.1) === -2 (-2.1) | (-2.1) === -2 .

Si sabe que solo está lidiando con números positivos menores que 2147483648, y necesita extraer todo el rendimiento de su código en navegadores antiguos (asegúrese de que en realidad es el cuello de botella, probablemente no). Yo usaría un método aún más simple: x|0 . No evalúa la variable dos veces, y funciona incluso si x es una expresión (solo asegúrese de ponerlo entre paréntesis para que no se encuentre con problemas de precedencia).


No tiene nada que ver con los navegadores modernos. Tiene que ver con la implementación del estándar ECMA. No se puede simplemente cambiar el rendimiento de una determinada función, incluso si hay una forma más rápida. Podría romper el código existente.

Math.Floor tiene que tener en cuenta una gran cantidad de escenarios diferentes para manejar diferentes tipos. ¿Podrían haber hecho diferentes escenarios más rápidos tomando atajos como describió? Tal vez podrían, pero eso podría haber roto otros escenarios. El hecho de que algo en la superficie parezca pequeño, no significa que no haya un iceberg debajo.