miércoles, 29 de abril de 2009

Optimización de bucles

Para comenzar nuestro periplo con la optimización de aplicaciones vamos a comenzar por algo fácil, muy probablemente ésto le parecerá obvio a muchos desarrolladores pero para todo aquel que empieza no vien mal una ayuda.

La primera medida a tener en cuenta es que debemos sacar del bucle todo aquellos valores invariables, ya que su computo no cambiará en las iteraciones (es lo que se suele llamar "invariantes del bucle").

 int r = 10;
for (int i=0; i<100; i++){
pi =3.14159;

float dist = pi*r*r;
}

En el ejemplo puede verse claramente que la variable pi debería situarse fuera del bucle, ya que de dejarlo así la asignación se ejecutará 100 veces en lugar de 1. Además de esto es importante sacar del bucle todo el código que no se usae estrictamente para el calculo que se quiere realizar en el bucle.

Otro aspecto importante que suele pasarse por alto es el calculo del limite en el bucle, muchas veces este limite se calcula mediante una función que ponemos en el mismo bucle, esto implica que dicha función se invoca una vez para cada iteración con su correspondiente coste.

 List lista = new ArrayList()
// inicializacion del list con 100 elementos.
lista.put("1");
...
lista.put("100");
for (int i=0; i<lista.size();i++){
...
}

Como vemos en el ejemplo la función size se invocará una vez por cada iteración. Una forma más optima para hacer esto es calculando el tamaño del bucle antes, como vemos a continuación:

 List lista = new ArrayList();
// inicializacion del list con 100 elementos.
lista.put("1");
...
lista.put("100");
int size = lista.size();
for (int i=0; i<size;i++){
...
}

Por último, otro aspecto a tener en cuenta al utilizar bucles es que usando las palabras reservadas continue y break podemos finalizar una iteración o el bucle completo. El uso de continue es interesante cuando dentro del blucle se comprueban ciertas condiciones que nos indicarán si el dato tratado en la iteración nos interesa o no, en caso de no quere tratarlo podemos ejecutar la instrucción continue para seguir con la siguiente iteración ahorrandonos el coste computacional del resto del cuerpo del bucle. El uso de break es muy útil en situaciones en las que buscamos un elelmento determinado dentro de una colección, en el momento que lo encontremos ejecutaremos un break y abortaremos la ejecucion del resto de iteracioen del bucle.

 List lista = new ArrayList();
// inicializacion del list con 10 elementos.
lista.put("1");
...
lista.put("10");
int size = lista.size();
for (int i=0; i<size;i++){
String element = lista.get(i);
if (element.equals("1")){
continue;
}
if (element.equals("5")){
break;
}

}

Como vemos inicialmente el bucle debería ejecutarse 10 veces, pero como estamos buscando el elemento 5 solo se ejecutara cinco veces, además de eso el primer elemento no comprobará la segunda condición ya que nos saltamos la iteración.

1 comentario:

  1. Realmente después de leer esta entrada me he quedado mucho más tranquila: no estoy tan verde como pensaba! XD
    Así que me pasaré a entradas de temas más avanzados ;-)

    Gracias por los consejos y las publicaciones que vas realizando.

    ResponderEliminar