Estoy usando Math.ceil(Math.abs(x))
dentro de un bucle.Javascript Math.ceil (Math.abs()) optimización
¿Alguien puede realizar alguna optimización para esta operación? (Bit a bit o qué?)
Usted es agradable de referencia en jsperf.com
Estoy usando Math.ceil(Math.abs(x))
dentro de un bucle.Javascript Math.ceil (Math.abs()) optimización
¿Alguien puede realizar alguna optimización para esta operación? (Bit a bit o qué?)
Usted es agradable de referencia en jsperf.com
Math.abs no recibe más simple de acuerdo con webkit JavaScriptCore
case MathObjectImp::Abs:
result = (arg < 0 || arg == -0) ? (-arg) : arg;
Sin embargo ceil utiliza la función ceil de C
case MathObjectImp::Ceil:
result = ::ceil(arg);
lo que las pruebas en JSpref http://jsperf.com/math-ceil-vs-bitwise a nivel de bits es más rápido
prueba de @ orangedog respuesta http://jsperf.com/math-ceil-vs-bitwise/2 Math.ceil es más rápido
así que supongo que su mejor opción es:
var n = Math.abs(x);
var f = (n << 0),
f = f == n ? f : f + 1;
¡Bien hecho, has hecho una gran investigación en la fuente de Webkit! – Dan
Javascript no es un lenguaje compilado como C, operaciones bit a bit por lo que puede hacer maravillas en estos idiomas, no son tan grandes en JS porque los números se almacenan como puntos flotantes de 64 bits. Eche un vistazo a este SO post.
Incluso entonces, lo que escriba en JS se transformará en código nativo de alguna manera por el navegador subyacente y podría ser más rápido o más lento, dependiendo de la implementación.
Dado que Math.ceil
y Math.abs
están incorporados; Supongo que están muy optimizados, así que dudo que puedas obtener un mejor rendimiento haciendo algunos trucos propios.
En pocas palabras: tres cosas se interponen en su camino de hacerlo más rápido:
te estás olvidando de sobrecarga de despacho - usar operadores en lugar de métodos acelerará el código – Christoph
Aunque aparentemente en los números JS todos son dobles, todos los motores JS realmente almacenan valores en enteros cuando sea posible, por lo que los operadores bit a bit siguen siendo rápidos ya que no se necesita conversión cuando el número ya es un número entero. – gsnedders
parseInt(Math.abs(x)) + 1
es más rápido en un 30% en Firefox acuerdo con jsperf
Como el argumento siempre es positivo, las ramas en Math.ceil() son innecesarias.
x < 0 ? Math.ceil(-x) : Math.ceil(x)
produce un aumento de velocidad del 40% en Firefox 3.6 (poca diferencia en los demás) mientras permanecen relativamente legibles.
Aquí está el jsPerf page. Ignore la etiqueta "algunos operadores bit a bit"; la expresión de arriba no usa ninguna.
Misma velocidad en Chrome –
I [encontrado con jsperf] (http://jsperf.com/two-max-bound-functions) que hacer algo de bit a bit es más rápido que una función de techo en este caso. – starwed
Dos maneras más rápidas de hacer cálculos (que dan casi la misma velocidad en los navegadores modernos):
function f (n) {
return (~~n) + 1;
}
// or
function f1 (n) {
return (n | 0) + 1;
}
// some tests, ~~ operator seems to work identicaly on numbers:
(3.3 | 0) === 3;
(3.8 | 0) === 3;
(-3.3 | 0) === -3;
(-3.8 | 0) === -3;
a diferencia Math.floor(-3.3) == Math.floor(-3.8) == -4
'f1 (1); // 2.' Estas funciones no siguen el comportamiento 'Math.ceil'. Tal vez deberías aceptar la respuesta mejor calificada, en lugar de la tuya. – MikeM
PS: Necesito el valor de retorno de la operación, no la condición es < or > algo – Dan
Me temo que no es más sencillo de lo que lo has hecho. –
He cambiado el valor de la prueba a un valor flotante negativo en lugar de un número entero, por lo que el código realmente tiene que hacer algo. – OrangeDog