Búsquedas

miércoles, 27 de mayo de 2009

Concatenar cadenas de caracteres en Java

En caso de tener la necesidad en nuestro código fuente de concatenar cadenas, tenemos la posibilidad de hacer uso de algunas clases que ofrece Java para ello. Esto es un requerimiento habitual para mensajes, errores, logs o excepciones.
Podemos hacer uso de
String o StringBuffer o StringBuilder, cualquiera de las tres realiza esta función, sin embargo, algunas presentan mejor rendimiento que otras.

String
Para realizar la concatenación usamos el operador + que está sobrecargado. Es la opción más habitual, sin embargo, también es la que peor rendimiento ofrece.
Al concatenar dos String, con el operador suma, se crea un nuevo String resultante, con lo que constantemente estamos creando objetos nuevos.

String hola = "Hola, ";
String mundo = "mundo";

String holamundo = hola + mundo;
StringBuffer
Esta clase permite concatenar caracteres de forma simple y eficiente.
Los métodos de StringBuffer son sincronizados, por lo que podemos usarlos de manera segura en un entorno multihilo.


StringBuffer holamundoBuffer = new StringBuffer();
holamundoBuffer.append("Hola, ");
holamundoBuffer.append("mundo);

String holamundo = holamundoBuffer.toString();

StringBuilder
Esta clase es nueva desde el JDK 5, y es la realmente recomendada para realizar la operación que estamos tratando. Su uso es idéntico al de StringBuffer.
Sus métodos no son sincronizados, por lo que tienen mejor rendimiento que StringBuffer. En general, la concatenación de String ocurre con variables locales a un método, por lo que es seguro usar StringBuilder en lugar de StringBuffer. En métodos que hacen uso intensivo de la concatenación, la diferencia en rendimiento puede ser importante.


StringBuilder holamundoBuilder = new StringBuilder();
holamundoBuilder.append("Hola, ");
holamundoBuilder.append("mundo");

String holamundo = holamundoBuilder.toString();

Rendimiento StringBuilder vs StringBuffer
Vamos a concatenar un millón de String ("zim") a un StringBuilder y a un StringBuffer y comparamos los tiempos:

 
StringBuffer sbuffer = new StringBuffer();
inicio = System.currentTimeMillis();
for (int i=0; i<1000000; i++) {
sbuffer.append("zim");
}
fin = System.currentTimeMillis();
System.out.println("Tiempo del StringBuffer: " + (fin-inicio));

StringBuilder sbuilder = new StringBuilder();
inicio = System.currentTimeMillis();
for (int i=0; i<1000000; i++) {
sbuilder.append("zim");
}
fin = System.currentTimeMillis();
System.out.println("Tiempo del StringBuilder: " + (fin-inicio));



Tras varias pruebas los tiempos se van haciendo constantes:
  • StringBuffer: 93 milisegundos
  • StringBuilder: 47 milisegundos


Por lo tanto, podemos observar que en la mayoría de los casos StringBuilder es casi un 50% más rápido en concatenar String.

Con el operador suma de String es una prueba que está fuera de lugar ya que tarda demasiado y puede producir desbordamientos de memoria y su rendimiento no es nada óptimo.

Por lo tanto, parece evidente que en la mayoría de los casos se debe hacer uso de StringBuilder para obtener un rendimiento máximo para realizar esta operación de concatenación de String.