Portada arrow Artículos arrow Bits de suciedad para evitar repetir operaciones costosas
Bits de suciedad para evitar repetir operaciones costosas
sábado, 24 de marzo de 2007

Bits de suciedadProgramando aplicaciones nos podemos encontrar con el caso de que una operación costosa en cuanto al tiempo de ejecución o al consumo de recursos en general (acceso a disco, red, etc...) se invoca varias veces, con el consecuente trabajo y consumo de recursos que conlleve, y sin embargo, es posible que los resultados nos valgan de una invocación para otra.

Si es ese el caso, podemos utilizar la técnica conocida como "bits de suciedad". Aunque se puede aplicar con programación imperativa, le sacaremos el máximo provecho en POO.

El nombre de bit de suciedad (dirty bit) se utiliza también en otros contextos. Por ejemplo, en un buffer o una memoria, se asocia un "bit de suciedad" para todos aquellos bloques de la memoria principal que difieren de su copia en memoria secundaria.

En nuestro caso, lo que haremos será asociar un bit a cada operación costosa (en tiempo u otros recursos) de nuestra clase que sepamos que es susceptible de ser solicitada más de una vez. Para representar a ese bit, utilizaremos un simple booleano.

Ese bit nos debe indicar si la operación debe realizarse o si nos vale el resultado de la última vez que lo ejecutamos. Si el bit de suciedad vale falso, significará que el resultado está "limpio", es decir, no necesita ser recalculado. Si el bit de suciedad vale verdadero, significará que el resultado está "sucio", es decir, necesita ser recalculado.

Vamos a construir una clase de ejemplo para ver esto. En este caso, nuestra clase representará a una simple lista de enteros, y le vamos a poner dos operaciones: una para añadir un nuevo entero al final de la lista, y otra para obtener el máximo de todos los enteros almacenados. Calcular ese máximo es una operación costosa.

Asociaremos un bit de suciedad (un booleano) a esa operación, y reservaremos una variable de instancia privada que represente al resultado de esa operación. Incialmente, pondremos el bit de suciedad a verdadero, es decir, el resultado no es válido.

En la operación de calcular el máximo, antes de empezar comprobaremos si el bit de suciedad es verdadero, y sólo en ese caso realizaremos la operación. Al terminar, pondremos el bit de suciedad a falso, indicando que el resultado es válido.

Cada vez que se añada un elemento nuevo al final de nuestra lista, el máximo podría cambiar, con lo cual dejaría de ser válido, así que cada vez que se añada un elemento, pondremos el bit de suciedad de la operación máximo a verdadero1.

Vamos a verlo (como de costumbre, es código en C#):

//clase de ejemplo para ilustrar el uso
//de bits de suciedad
public class EjemploBitsSuciedad
{
   //nuestro array de enteros
   int[] v;
   //un índice que nos lleve la cuenta
   //de enteros en el array
   int cuenta;
 
   //el resultado de la operación máximo
   int maximo;
   //el bit de suciedad de la operación
   //máximo
   bool maximoSucio;
 
   //El constructor
   public
   EjemploBitsSuciedad()
   {
      //damos dimensión al array
      v=new int[1000];
      //inicialmente vacío
      cuenta=0;
 
      //el resultado del máximo no es válido
      maximo=int.MinValue;
      maximoSucio=true;
   }
 
   //añadir un entero al final del array
   public
   void Agregar(int i)
   {
      v[cuenta]=i;
      i++;
      //ponemos el bit de suciedad de la operación
      //máximo a true, porque si previamente teníamos
      //un máximo válido, al insertar un nuevo
      //elemento, ya no tienen por qué serlo
      maximoSucio=true;
   }
 
   public
   int ObtenerMaximo()
   {
      //sólo calculamos el máximo si está "sucio"
      if (maximoSucio) 
      {
         //este mensaje es sólo para ver
         //cómo funciona esto
         Console.WriteLine("VAMOS A CALCULAR EL MÁXIMO");
         //en este bucle calculamos el máximo
         foreach(int i in v)
         {
            if(i>maximo)
                maximo=i;
         } //foreach
         //después de calcularlo, el máximo está "limpio"
         maximoSucio=false;
      } //if
      else
      {
         //el else y este mensaje es sólo para ver como
         //funciona esto
         Console.WriteLine("EL MAXIMO ANTERIOR AUN VALE");
      } //else
   return maximo;
   }
 
} //fin de la clase
 
 

Hagamos una prueba... Instanciamos la clase, añadimos unos enteros y vamos pidiendo el máximo de vez en cuando, a ver qué mensajes salen...

public static void Main(string[] args)
{
   EjemploBitsSuciedad ej=new EjemploBitsSuciedad();
   ej.Agregar(3);
   ej.Agregar(4);
   ej.Agregar(9);
   ej.Agregar(2);
   Console.WriteLine(ej.ObtenerMaximo());
   Console.WriteLine(ej.ObtenerMaximo());
   ej.Agregar(10);
   Console.WriteLine(ej.ObtenerMaximo());
   Console.WriteLine(ej.ObtenerMaximo());
 
}
 

Por la consola observaremos ésta salida

VAMOS A CALCULAR EL MAXIMO
9
EL MAXIMO ANTERIOR AUN VALE
9
VAMOS A CALCULAR EL MAXIMO
10
EL MAXIMO ANTERIOR AUN VALE
10
 

Es decir, la primera vez que pedimos el máximo después de agregar, realmente se calcula con el bucle, porque el resultado está "sucio". Al pedirlo una segunda vez sin agregar por enmedio, como el resultado está "limpio", no se calcula, sino que se devuelve el anterior.

Además, la utilización del bit de suciedad es totalmente transparente a la hora de utilizar la clase.

Esta técnica es ampliamente utilizada en situaciones como ésta, y sobre todo, en algunas que implican E/S, que suelen consumir gran cantidad de tiempo y recursos. Por ejemplo, obtener datos desde un SGBD, un servicio de red, etc.

La técnica de los bits de suciedad también ayuda a paliar el efecto negativo del desliz que comentábamos hace unos días en el cual se incluyen operaciones costosas no necesarias en el interior de los bucles.

1: Ya sé que en este caso se puede ir calculando el máximo a medida que añadimos, pero ésto es sólo un ejemplo.

 
←Artículo anterior   Artículo siguiente→

Categorías

  • Ingeniería del software  ( 4 artículos )

    Acerca de la ingeniería del software y el ciclo de vida del software.

  • El programador elegante  ( 12 artículos )
    Una serie de artículos dedicados a buenas prácticas en programación
  • Opinión  ( 7 artículos )

    Artículos de opinión, no necesariamente fundamentada.

  • Básico  ( 12 artículos )

    Artículos básicos sobre temas básicos.

     

¿Quién está en línea?

 web tracker

Suscríbete

RSS feed Sindicación RSS

(¿Qué es la sindicación RSS?)


Suscribir por e-mail

¿Dónde estoy?

Estás en La tecla de ESCAPE, un sitio web personal en el que nos gusta hablar de algoritmos, informática, tecnología, ciencia, ingeniería, internet... y cualquier tontería que se nos ocurra. El punto de vista de nuestros artículos técnicos suele ser muy básico, así que a menudo adoptamos grandes simplificaciones. (Más...-Términos de uso)