Supongamos que tenemos la siguiente función que calcula la suma de todos los números de 1 a N.
function sumarNumeros(n) {
let suma = 0;
for (let i = 0; i <= n; i++) {
suma += i;
}
return suma;
}
El mismo resultado se puede obtener con la siguiente función.
function sumarNumeros(n) {
return (n * (n + 1)) / 2;
}
Para determinar cual de las dos funciones es mejor tenemos que cuestionarnos.
- ¿Cuál es la función mas rápida?
- ¿Cuál utiliza menos memoria?
- ¿Cuál es mas sencilla de entender?
De las opciones anteriores las dos que suelen ser mas importantes son mayor rapidez y menor consumo de la memoria.
¿Qué es el timing (cronometraje)?
El timing (cronometraje) consiste en medir el tiempo que toma a un algoritmo completar su ejecución, esto permite medir la velocidad con la que es capaz de completar una tarea.
Una forma de hacerlo en JavaScript es calculando el tiempo entre el punto antes de ejecutar la función y después de completarla. Para ello podemos usar el objeto performance.
function sumarNumeros(n) {
let suma = 0;
for (let i = 0; i <= n; i++) {
suma += i;
}
return suma;
}
const time1 = performance.now();
console.log(sumarNumeros(1000));
const time2 = performance.now();
console.log("El tiempo de ejecución es", time2 - time1);
500500
El tiempo de ejecución es 3.092143999878317
Si ejecutamos varias veces el mismo código este nos entregará diferentes resultados en relación al tiempo.
Ahora con la segunda función.
function sumarNumeros(n) {
return (n * (n + 1)) / 2;
}
const time1 = performance.now();
console.log(sumarNumeros(1000));
const time2 = performance.now();
console.log("El tiempo de ejecución es", time2 - time1);
500500
El tiempo de ejecución es 2.6364869996905327
Como podemos ver esta función se ejecuta de manera mas rápida comparada con la anterior.
¿Por qué el timing no es una solución adecuada?
Los problemas que presenta el timng al momento de medir el la velocidad son:
- Diferentes equipos reportarán diferentes tiempos de ejecución.
- El mismo equipo va a reportar diferentes tiempos de ejecución.
- Para algoritmos rápidos, la medición de la velocidad no será precisa.
¿Cuál es la alternativa al timing?
En lugar de contar segundos una posible solución los cuales siempre serán variables, una mejor opción es contar operaciones que el computador tiene que realizar.
En esta función…
function sumarNumeros(n) {
return (n * (n + 1)) / 2;
}
Tenemos las operaciones…
- Una multiplicación (*)
- Una suma (+)
- Una división \
Tenemos 3 operaciones, es decir N = 3
Ahora analizamos la otra función que utiliza un bucle.
function sumarNumeros(n) {
let suma = 0;
for (let i = 0; i <= n; i++) {
suma += i;
}
return suma;
}
Tenemos las operaciones…
- Una asignación (suma = 0)
- Una asignación (i = 0)
- n comparaciones (i<=n)
- n incremetos (i++)
- n asignaciones (i++)
- n sumas (total += i)
- n igualdades (total += i)
Dependiendo del valor de n, la función puede llegar a ser tan compleja como 5n + 2.
En este segundo ejemplo el numero de operaciones incrementa proporcionalmente en base al valor de n.