jueves, 30 de julio de 2009

Almacenamiento en caché de objetos Java: Cache vs Pool

Abriendo un paréntesis, algunos pueden confundirse con un concepto similar pero a su vez diferente: Pool de Objetos. Ambos, "cacheo" y "pooleo" son usados para un mismo propósito general, mejorar el rendimiento al reducir el costo de crear ciertos objetos que consumen recursos vitales (tiempo, ancho de banda, memoria, etc).
La diferencia principal es que el pool de objectos no requiere "unicidad" de los objetos que son almacenados. En otras palabras, para cierta necesidad, cualquier objeto guardado en el pool puede hacer el trabajo. De esta manera el pool puede balancear las solicitudes para cierto objeto al mantener varias instancias para devolverlos de manera inmediata. Cache por contraste requiere que un objeto sea mapeable, esto es que pueda ser identificado por una llave única (esta llave puede ser una llave compuesta como veremos después en los siguientes posts). Para este caso, cualquier objeto no puede hacer el trabajo, se necesita un objeto especifico y debemos poder tener la facultad de contruit la llave para el almacenamiento y recuperación del objeto.

Para ejemplificar esto podemos pensar en una aplicación hipotética que trabaje con instancias de una clase llamada "Persona". Supongamos que un proceso de negocio requiere obtener una persona, cualquier persona de manera aleatoria. Debido a que el proceso para construir a la persona requiere de varios llamados a una base de datos, un pool es implementado de manera que cierto número de instancias de la clase Persona son mantenidas in memoria local. La aplicación por tanto haría un llamado similar a esto:



PersonaPool.solicitarPersona();



Ahora si otro proceso requiere obtener una persona en especifico identificable por un ID, requieriendo tambi[en hacer una serie de llamados a la base de datos para la construcci[on del objeto, un diseño de cache seria necesario para evitar el alto costo de realizar todos estos llamados a la base de datos. La aplicación por tanto haría un llamado como este:



PersonaCache.obtenerPersona('125677');



El pool de objetos es una técnica usada ampliamente en aplicaciones que requieren abrir conexiones con una base de datos a traves de objetos de conexión. No obstante debemos tener siempre la mente abierta para aprovechar cualquier buena oportunidad para usarla en nuestras aplicaciones.

martes, 30 de junio de 2009

Almacenamiento en caché de objetos Java: Introducción


Si usted va a una tienda en busca de algo de ropa, digamos un par de pantalones y tres camisetas, probablemente al igual que el resto de nosotros usted hará lo siguiente: camina alrededor, toma algunas piezas que le gusta y las lleva al cambiador. Usted no puede tomar todo el departamento consigo a esta pequeña habitación de modo que tiene que elegir cuidadosamente las prendas que más llaman su atención. Una vez que pruebe algunas piezas, se quedará con algunas y descartará otras, así que tendrá que repetir el proceso el número de veces que sea necesario para conseguir todo lo que anda buscando.

Y ahora, ¿qué ocurre si en lugar de tomar todas las piezas que se permite al cambiador, usted toma sólo una pieza a la vez. Es probable que dure tres o cuatro veces más, sin mencionar la curiosidad de la persona que administra el cambiador. Esta actividad de sentido común: aumentar al máximo la cantidad de ropa al alcance de la mano a la hore de probarse la ropa, es a veces no tan evidente para algunos desarrolladores de software . Tengo que admitir que no era tan evidente para mi tampco.

El concepto es bien concocido no obstante, CACHE. La primera vez que escuché la palabra cache fue cuando tuve mi primer PC. El vendedor muy orgulloso con los tecnisismos de su vocabulario, mencionaba que el micro procesador tenía ~ ~ k bytes de memoria caché. Siendo yo uno adolescente todo eso me sonaba a chino, aunque me dio la sensación de que caché era algo super importante.

Unos pocos años pasaron y aterricé en un curso de Arquitectura de Computadores en la universidad en el que se me explicó la importancia de una buena estrategia de caché para el buen desempeño de un micro-procesador. Incluso tuvimos que programar un emulador de caché así como un administrador de la jerarquía de memoria (cómo gestionar los datos que se asignan a los diferentes niveles de memoria: registros, caché, RAM, disco). Sin embargo, parece que mis neuronas no estaban muy productivas ese semestre porque no hicieron una conexión con mis neuronas de arquitectura de software.

No es como si hubiera un problema de rendimiento antes en mis aplicaciones, sólo fue un tipo de nuevo descubrimiento al averiguar acerca de la existencia de sistemas Java especializados en almacenamiento de objetos en caché En el próximo post voy a seguir describiendo el sistema que he estado usando por un tiempo: Jakarta: JCS (“Java Caching System”) y por qué considero que es una necesidad en aplicaciones distribuidas.

lunes, 15 de junio de 2009

Ordenamiento de mapas

Hace un tiempo me tocó buscar como forzar el orden FIFO ("First in First out") en un mapa. Cuando usaba un HashMap siempre obtenía un orden aleatorio y el TreeMap no me servía por su ordenamiento alfabético. Para estos casos existe la clase LinkedHashMap. Veamos el comportamiento para cada uno de los mapas mencionados.

HashMap



import java.util.HashMap;

public class Mapas{

public static void main(String[] args) {
Map<string, Integer> promedios = new HashMap<string, Integer>();
promedios.put("Blanca", 95);
promedios.put("Gabriel", 90);
promedios.put("Daniela", 85);
promedios.put("Juana", 70);
promedios.put("Alejandro", 50);

for (Iterator<string> keys=promedios.keySet().iterator(); keys.hasNext();) {
String estudiante = keys.next();
int promedio = promedios.get(estudiante);
System.out.println(estudiante + ": " + promedio);
}
}
}
Salida:

Blanca: 95
Juana: 70
Gabriel: 90
Alejandro: 50
Daniela: 85



TreeMap


import java.util.TreeMap;

public class Mapas{

public static void main(String[] args) {
Map<string, Integer> promedios = new TreeMap<string, Integer>();
promedios.put("Blanca", 95);
promedios.put("Gabriel", 90);
promedios.put("Daniela", 85);
promedios.put("Juana", 70);
promedios.put("Alejandro", 50);

for (Iterator<string> keys=promedios.keySet().iterator(); keys.hasNext();) {
String estudiante = keys.next();
int promedio = promedios.get(estudiante);
System.out.println(estudiante + ": " + promedio);
}
}
}
Salida:

Alejandro: 50
Blanca: 95
Daniela: 85
Gabriel: 90
Juana: 70


LinkedHashMap

import java.util.LinkedHashMap;

public class Mapas{

public static void main(String[] args) {
Map<string, Integer> promedios = new LinkedHashMap<string, Integer>();
promedios.put("Blanca", 95);
promedios.put("Gabriel", 90);
promedios.put("Daniela", 85);
promedios.put("Juana", 70);
promedios.put("Alejandro", 50);

for (Iterator<string> keys=promedios.keySet().iterator(); keys.hasNext();) {
String estudiante = keys.next();
int promedio = promedios.get(estudiante);
System.out.println(estudiante + ": " + promedio);
}
}
}

Salida:

Blanca: 95
Gabriel: 90
Daniela: 85
Juana: 70
Alejandro: 50

martes, 2 de junio de 2009

Resaltador de Sintáxis para tu código


Recientemente implementé un resaltador de sintáxis en este blog para que el código que publicara fuera fácilmente leíble por cualquiera. Anteriormente intentaba yo darle formato usando las herramientas de formato de blogger pero me di cuenta que perdía demasiado tiempo en esta tarea y al final el código seguía luciendo mal.
Así que un día de tantos mientras leía un blog, ví un comentario de un lector que sugería usar un "Sintax Highlighter", vaya como cuesta a veces buscar algo en Google cuando no tienes la frase correcta. Ahí estaba la solución para mi código plano y sin color.

De esta manera aterricé al proyecto: "Sintax Highlighter" que hace justamente lo que necesitaba.

Implementación:

Para usar el resaltador necesitas descargar el proyecto del sitio que incluye todos los javascripts y CSS's que debes subir a tu servidor para referenciarlos en tu código.

Para los pobres o tacaños como su servidor que no hemos adquirido los servicios de un hosting o demasiado vagos para buscar uno gratuito, también se puede referenciarlos directamente del proyecto como lo hago yo en este blog:


<link href='http://syntaxhighlighter.googlecode.com/../SyntaxHighlighter.css' rel='stylesheet' type='text/css'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/../shCore.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/../shBrushCSharp.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/../shBrushXml.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/..s/shBrushPython.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/../shBrushJScript.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/../shBrushPhp.js'/>

Claro está que esta referencia hace un poco más lenta la carga de la página y no garantiza que los archivos referenciados estarán siempre en el servidor del proyecto. Lo recomendable es subirlo en tu propio servidor.

Para activar el resaltador en tu página debes de correr el siguiente código inmediatamente después de la etiqueta <body>:


<script language='javascript'>
dp.SyntaxHighlighter.BloggerMode();
dp.SyntaxHighlighter.HighlightAll('code');
</script>
</html>
La primera línea indica al resaltador que mi página es un blog (necesario para adecuar el formato correctamente). Después se invoca al resaltador con la función HighlightAll.

Cómo usarlo?


Para resaltar un código simplemente abres una etiqueta "pre" y le asignas al atributo "name" el valor "code" y al atributo "class" el nombre del lenguaje que estás utilizando:
  • javascript
  • html
  • java
  • c-sharp
<pre name="code" class="html">
Put html code here!
<pre>

Ejemplos

HTML


<html>
<body>
<head>
</head>
Body Code here!
</body>
</html>


Javascript


function pow(int x) {
return x * x;
}


Java (Collapsed)


public class Hello {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}