Optimización de código–Parte II

Continuando con el post anterior, vamos a ver un par de soluciones. Por supuesto, estas aplican principalmente a JavaScript y su forma de trabajo. Tal vez, otros lenguajes requieran de otro acercamiento, lo que nos lleva una cuestión crucial: Necesitamos saber cómo usar el lenguaje.

Si lo anterior no lo tenemos, o sea, si no conocemos el lenguaje que usamos, es posible que estemos haciendo código para resolver tareas cuando ya existe una solución para ese caso.

Un ejemplo muy simple puede ser lo siguiente:

var r;
var a = 10;
var b = 11;
if (a < b) {
   r = a;
} else {
   r = b;
}
console.log(“El número menor es: “ + r);

El código anterior puede ser reducido muy fácilmente:

var a = 10;
var b = 11;
var r = Math.min(a, b);
console.log(“El número menor es: “ + r);

Lo importante es entender que no reducimos código quitando variables o quitando líneas en blanco. El código se reduce bajando la cantidad de ciclos o procesos de análisis que se tienen que hacer para ejecutar determinada tarea. Y si bien remover variables u objetos no utilizados ayuda y siempre que podamos deberemos hacerlo, hablamos principalmente de que tan óptimo es nuestro código.

Pero retomemos el desafío original. Algunas de las propuestas que me llegaron se centraron en la reducción de variables, y la ejecución de código en una sola línea. Esto es, ahorrar la asignación de datos de una variable a la otra. Esto claramente aumenta la performance de nuestro código. Evitar el ida y vuelta a la memoria, el boxing y unboxing (Si fuese aplicable), mejorará el funcionamiento.

Un ejemplo:

this.doTask = function (v) {
    return (stack.pop())(v);
};

En este caso, al momento de quitar un elemento de la pila, en vez de asignarlo a una variable y luego ejecutar la función, se hace todo en un solo paso (Quitar, ejecutar, retornar resultado de ejecución).

Nos ahorramos una variable, un par de asignaciones (Idas y vueltas). Una mejora interesante.

Pero aún podemos compactar más el código. Veamos otro ejemplo:

function worker2() {
    var self = this;
    var stack = [];
    this.addToStack = function (f) {
        stack.push(f);
    };
    this.canUnStack = function () {
        return (self.doTask = stack.pop());
    };   
    this.doTask = function () {    };
}

Como decía antes, puede que solo sea aplicable a JavaScript o lenguajes similares, de cualquier manera, vemos que este código elimina absolutamente el código de la función doTask, e incluso compacta (Brutalmente) el código de canUnStack.

Ahora canUnStack se encarga de quitar elementos de la pila de funciones y modificar la referencia devuelta a la función doTask. Con esto, el programador estaría ejecutando la función específica cada vez que llama a doTask, y no ejecutando un proceso intermedio de selección. También, la asignación, quitado de la pila y verificación de si puede o no quitar elementos de la misma, se hace en un solo paso dentro de canUnStack.

Para comprobar que efectivamente hubo una mejora, usé JsLitmus a modo de prueba. Donde el primer test prueba el código optimizado, y el segundo prueba el código sin optimizar.

Untitled

Si bien JsLitmus tiene sus cosas y podemos dudar un poco de los resultados, la diferencia en operaciones realizadas por segundo es abrumadora.

En resumen: Optimizar el código siempre será una buena práctica. Conocer el lenguaje que utilizan, otra.



Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s