20/9/2007 16:26 El Bruno

[VS2005] Strings vs StringBuilders

Buenas

después del minipost de hace unos días sobre la utilización de String.IsNullOrEmpty en el desarrollo de aplicaciones; alguien me preguntó porque String vs StringBuilders. Ya se que este no es un tema nuevo y que seguramente mucha gente lo conoce, pero para los que no estén al tanto, un consejo: "ojo con el enfoque que le dan a sus aplicaciones si tienes un proceso de cadenas string muy intensivo".

¿Porqué digo esto? porque en .Net los string son objetos rígidos, es decir, no es posible concatenar strings dentro del objeto strings. Si bien podemos utilizar la función Concat(), para cada nuevo String que procesamos, el string original se destruye y uno nuevo se crea en su lugar.

Como siempre la mejor forma de demostrarlo en con código, y para esto rescato una clase que hace muchísimo escribí para una demo:

1 class Program 2 { 3 /// <summary> 4 /// Mains the specified args. 5 /// </summary> 6 /// <param name="args">The args.</param> 7 static void Main(string[] args) 8 { 9 // 1000 operations 10 TestString(1000); 11 TestStringBuilder(1000); 12 13 // 5000 operations 14 TestString(5000); 15 TestStringBuilder(5000); 16 17 // 10000 operations 18 TestString(10000); 19 TestStringBuilder(10000); 20 21 // 50000 operations 22 TestString(50000); 23 TestStringBuilder(50000); 24 25 // 100000 operations 26 TestString(100000); 27 TestStringBuilder(100000); 28 29 Console.WriteLine("Finish process test ..."); 30 Console.ReadKey(); 31 } 32 33 /// <summary> 34 /// Tests the string. 35 /// </summary> 36 /// <param name="count">The count.</param> 37 public static void TestString(int count) 38 { 39 DateTime dtStart = DateTime.Now; 40 string ret = string.Empty; 41 for (int i = 0; i < count; i++) 42 { 43 ret += i.ToString(); 44 } 45 DateTime dtEnd = DateTime.Now; 46 TimeSpan tsDif = dtEnd - dtStart; 47 Console.WriteLine(string.Format("For {0} operations Using Strings: {1} seconds", count, tsDif.Seconds.ToString())); 48 } 49 50 /// <summary> 51 /// Tests the string builder. 52 /// </summary> 53 /// <param name="count">The count.</param> 54 public static void TestStringBuilder(int count) 55 { 56 DateTime dtStart = DateTime.Now; 57 StringBuilder sb = new StringBuilder(); 58 for (int i = 0; i < count; i++) 59 { 60 sb.Append( i.ToString() ); 61 } 62 DateTime dtEnd = DateTime.Now; 63 TimeSpan tsDif = dtEnd - dtStart; 64 Console.WriteLine(string.Format("For {0} operations Using StringBuilder: {1} seconds", count, tsDif.Seconds.ToString())); 65 } 66 } 67

 

Como pueden ver, esta aplicación de Consola crea y concatena strings en un determinado numero de ocasiones y durante el proceso, toma los tiempos de inicio y fin para poder tener la diferencia de los mismos. El output de la consola es bastante explícito en cuando a las relaciones

 

For 1000 operations Using Strings: 0 seconds

For 1000 operations Using StringBuilder: 0 seconds

For 5000 operations Using Strings: 0 seconds

For 5000 operations Using StringBuilder: 0 seconds

For 10000 operations Using Strings: 0 seconds

For 10000 operations Using StringBuilder: 0 seconds

For 50000 operations Using Strings: 10 seconds

For 50000 operations Using StringBuilder: 0 seconds

For 100000 operations Using Strings: 55 seconds

For 100000 operations Using StringBuilder: 0 seconds

Finish process test ...

 

Saludos @ Madrid

El Bruno

Crossposting from ElBruno.com
Archivado en: ,
Comparte este post:

# re: [VS2005] Strings vs StringBuilders

Thursday, September 20, 2007 9:24 PM by Romny

Este post esta interesante. hace tiempos no miraba esa comparacion.

# re: [VS2005] Strings vs StringBuilders

Friday, September 21, 2007 9:00 AM by Juan

Muy interesante, quizás a primera vista, para un novato, puede ser que parezca más laborioso y costoso (tanto en recursos del sistema como en programación por parte del programador) usar StringBuilder. Pero queda demostrado que no, que es muchísimo más efectivo el uso de StringBuilder que una simple concatenación de string.

# re: [VS2005] Strings vs StringBuilders

Friday, September 21, 2007 2:14 PM by Juan Fco. Berrocal

Muy interesante el ejemplo bruno, pues tendre que probarlo a ver de que va eso del StringBuilder, aunque noto que estas usando C# y eso es bueno Big Smile

Un Saludo

# re: [VS2005] Strings vs StringBuilders

Friday, September 21, 2007 10:46 PM by Anonimo

Formidable, si señor Formidable. Con posts así de profundo y de calidad avanzada es lo que hace de Geeks.ms lo que es. Completamente formidable querido Bruno. Bien hecho. Si Señor!!!!!

# re: [VS2005] Strings vs StringBuilders

Saturday, September 22, 2007 7:01 AM by christian ruiz

pues no hay nada novedoso en el tema mas si un consejo para nosotros los programadores deberia tambien hablarse sobre el uso del and y andelse que es un tema sencillo pero interesante.

saludos

developernetx@hotmail.com

# re: [VS2005] Strings vs StringBuilders

Saturday, September 22, 2007 6:02 PM by El Bruno

Juan u're right

Juan Fco tienes razón ... demasiado C# en estos días (espero que no se haga costumbre ... )

Anónima, gracias.

Christian, pues invitado estas a escribir algo sobre los comparadores, nunca viene mal repasar esos temas, aunque lo veo mas para programancia 101 :D

Saludos

# re: [VS2005] Strings vs StringBuilders

Sunday, September 23, 2007 11:54 PM by CHRISTIAN RUIZ

pues quisiera hablar sobre el and y andelse (cortocircuito). jejeje pero no me dan permiso en esta portal para realizar tal consejito en estos momentos. saludos

# re: [VS2005] Strings vs StringBuilders

Monday, September 24, 2007 8:55 AM by Pablo Alarcón García

Añadir que la diferencia de tiempos es fundamentalmente porque cada concatenación de strings crea un nuevo string, provocando en un bucle un trashing ( creación de memoria basura ya que no se usa ) salvaje.

En cambio el StringBuilder sólo crea un string cuando al final sacas el contenido concatenado.

PD: Christian, si hablas del And y el AndElse deja claro que en C#, y cualquier lenguaje herencia de C, los And cortocirtuitan como hace el AndElse de VB.NET, es un tema que confunde a mucha gente entre VB.NET y C#.

# re: [VS2005] Strings vs StringBuilders

Thursday, January 10, 2008 6:25 AM by CHRISTIAN RUIZ

LES DEJO ALGUITO:

namespace PerformanceGenerics

{

   class Program

   {

       // Cantidad de vueltas que vamos a usar para nuestro Test

       private const int QTD_ITENS = 10000;

       static void Main(string[] args)

       {

                for (int I = 0; I < 20; I++)

               {

                   EjecutarStringBuil();

                   EjecutarStr();

                   //ExecutaProcesoSinGenerics();

                  // ExecutaProcesoConGenerics();

               }

             Console.ReadKey();

       }

       private static void EjecutarStr()

       {

           List<int> Lista = new List<int>();

           int ContadorInicio = 0;

           int ContadorFim = 0;

      string str="";

      ContadorInicio = Environment.TickCount;

             for (int I = 0; I < QTD_ITENS; I++)

                         str += " mama";

           ContadorFim = Environment.TickCount;

           Console.WriteLine("Tiempo procesado con Concatenacion: "

               + (ContadorFim - ContadorInicio).ToString());

       }

       private static void EjecutarStringBuil()

       {

           List<int> Lista = new List<int>();

           int ContadorInicio = 0;

           int ContadorFim = 0;

           ContadorInicio = Environment.TickCount;

           StringBuilder Str = new StringBuilder();

           for (int I = 0; I < QTD_ITENS; I++)

               Str.Append(" mama");

              ContadorFim = Environment.TickCount;

           Console.WriteLine("Tiempo procesado con StringBuilder: "

               + (ContadorFim - ContadorInicio).ToString());

       }

       private static void ExecutaProcesoConGenerics()

       {

           // creamos una lista usando genericos de tipo List

           List<int> Lista = new List<int>();

           int ContadorInicio = 0;

           int ContadorFim = 0;

           ContadorInicio = Environment.TickCount;

           int Total = 0;

           //agregamos los elementos a la lista

           for (int I = 0; I < QTD_ITENS; I++)

               Lista.Add(I);

               for (int I = 0; I < QTD_ITENS; I++)

               Total += ListaIdea;

           ContadorFim = Environment.TickCount;

           // muestra cuantos milissegundos fueron necesitados

           // para ejecutar el proceso

           Console.WriteLine("Tiempo procesado con genericos: "

               + (ContadorFim - ContadorInicio).ToString());

       }

       private static void ExecutaProcesoSinGenerics()

       {

           // creamos un arraylist

           System.Collections.ArrayList Lista = new System.Collections.ArrayList();

           int ContadorInicio = 0;

           int ContadorFim = 0;

           ContadorInicio = Environment.TickCount;

           int Total = 0;

           // agregamos items

           for (int I = 0; I < QTD_ITENS; I++)

               Lista.Add(I);

           for (int I = 0; I < QTD_ITENS; I++)

               Total += (int)ListaIdea;

           ContadorFim = Environment.TickCount;

           // muestra cuantos milissegundos fueron necesitados

           // para ejecutar el proceso

           Console.WriteLine("Tiempo procesado sin  genericos: "

               + (ContadorFim - ContadorInicio).ToString());

       }

   }

}