10 de diciembre de 2009

Concatenación de String (String vs StringBuilder)

Recientemente tuve que analizar el código de una página Web que presentaba un comportamiento bastante ineficiente.

Para focalizar el problema utilicé una excelente herramienta que no viene al caso ahora. En fin que después de detectado y analizado el método donde se producía el cuello de botella, descubrimos que la ineficiencia se debía a la actualización de una variable de tipo string dentro de un ciclo medianamente grande, para que me entiendan, el código despejándolo un poco era algo así:

public string ConcatenacionIneficiente()
{
  //Ejemplo de código ineficiente
  string strResult = string.Empty;
 
  for (int i = 0; i < 50000; i++)
  {
    //…
    strResult += i;
    //…
  }
 
  return strResult;
}

Al detectar semejante mala práctica, modificamos el código dejándolo de la siguiente manera:

public string Concatenacion()
{
    //Ejemplo de código eficiente
    StringBuilder sbResult = new StringBuilder();
 
    for (int i = 0; i < 50000; i++)
    {
        //…
        sbResult.Append(i.ToString());
        //…
    }
 
    return sbResult.ToString();
}

Como verán la diferencia entre un código y el otro es que remplazamos el uso de una variable string por otra de tipo StringBuilder. Y el resultado es el mismo pero con una notable mejora de eficiencia.

Explicación:

Las cadenas de .Net Framework son invariables (o sea, el texto al que se hace referencia es de sólo lectura después de la asignación inicial). Esto provoca que internamente, para concatenar un string, lo que se hace es crear una nueva instancia de string, copiar el string actual en esa nueva instancia y borrar la instancia original.

Conclusión:

La concatenación de strings es extremadamente ineficiente. Siempre que se pueda, aunque sea para las operaciones más simples, utilizaremos el StringBuilder frente a la concatenación de strings... y si es para operaciones más costosas ni lo pensaremos!!!!