lunes, 17 de marzo de 2008

StringBuilder vs. concatenación de String

Trabajando para la última versión de GeneXus (Rocha) me tocó escribir algunas sentencias SQL. Como hasta ahora hice siempre, empecé declarando una variable string con la sentencia y a esta le concatenaba los parámetros que fuera necesario*.
Pero en determinado momento, Milano me recomendó como buena práctica, utilizar StringBuilder para concatenar strings, en lugar de la fácil y práctica forma de concatenación con el '+'.

Pero por qué? "se supone que es mas eficiente" me dijo... "no es que esa concatenación vaya a significar una demora en el proceso, pero es una práctica recomendable utilizar StringBuilder".

No es que desconfíe de el :) pero me interesó hacer una prueba para ver que tan eficiente era, y los resultados de esa prueba me motivaron este post asique acá están.

Primero voy a mostrar la prueba que hice. El main es el siguiente:

 

string text = "First text";
int i = 100000;

DateTime start;
DateTime end;
TimeSpan duration;

start = DateTime.Now;
InsertString(text, i);
end = DateTime.Now;
duration = end - start;
Console.WriteLine(string.Format("InsertString took {0}:{1} seconds", duration.Seconds, duration.Milliseconds));

start = DateTime.Now;
InsertStringBuilder(text, i);
end = DateTime.Now;
duration = end - start;
Console.WriteLine(string.Format("InsertStringBuilder took {0}:{1} seconds", duration.Seconds, duration.Milliseconds));

Como verán, simplemente tomo el tiempo antes y después de cada llamada y luego imprimo la diferencia en segundos y milisegundos para saber cuanto demoró cada función. La funciones InsertString e InsertStringBuilder son muy básicas pero también las pegaré acá:

private static void InsertString(string text, int i)
{
for (int j = 0; i >= j; j++)
text += " new text";
}

private static void InsertStringBuilder(string text, int i)
{
StringBuilder builder = new StringBuilder(text);
for (int j = 0; i >= j; j++)
builder.Append(" new text");
}

Dije que eran básicas :)
Pues bien, ahora el resultado...


StringBuilder


Bastante increible no? por lo menos a mi me llamó enormemente la atención, más de 20 segundos contra menos de 1!. Obviamente esta diferencia se hace muy notoria por la cantidad de iteraciones que tiene la concatenación, si solo es concatenar un string con otro una única vez, posiblemente no valga la pena utilizar el StringBuilder.


*Nota: si los parámetros son ingresados por el usuario final de la aplicación esta no es una buena práctica. Podemos llegar a ser víctimas de SQL Injection.

No hay comentarios.: