Pregunta

Entiendo los beneficios de StringBuilder.

Pero si quiero concatenar 2 cadenas, entonces supongo que es mejor (más rápido) hacerlo sin StringBuilder. ¿Es esto correcto?

¿En qué punto (número de cadenas) es mejor usar StringBuilder?

¿Fue útil?

Solución

Le sugiero que lea La triste tragedia del teatro de micro-optimización , por Jeff Atwood.

Trata la concatenación simple frente a StringBuilder frente a otros métodos.

Ahora, si desea ver algunos números y gráficos, siga el enlace;)

Otros consejos

  

Pero si quiero concatinar 2   cadenas, entonces supongo que es   mejor (más rápido) hacerlo sin   StringBuilder. ¿Es esto correcto?

Eso es correcto, puede encontrar por qué exactamente se explica muy bien en:

http://www.yoda.arachsys.com/csharp/stringbuilder.html

Resumido: si puede concatenar cadenas de una vez, vaya como

var result = a + " " + b  + " " + c + ..

está mejor sin StringBuilder ya que solo se realiza una copia (la longitud de la cadena resultante se calcula de antemano);

Para estructura como

var result = a;
result  += " ";
result  += b;
result  += " ";
result  += c;
..

se crean nuevos objetos cada vez, por lo que debe considerar StringBuilder.

Al final, el artículo resume estas reglas generales:

  

Reglas generales

     

Entonces, ¿cuándo deberías usar StringBuilder,   y cuando deberías usar la cadena   operadores de concatenación?

     
      
  • Definitivamente use StringBuilder cuando   estás concatenando en un no trivial   bucle, especialmente si no sabes   seguro (en tiempo de compilación) cuántos   iteraciones que harás a través del   lazo. Por ejemplo, leyendo un archivo a   personaje a la vez, construyendo un   cadena a medida que avanza utilizando el operador + =   es potencialmente suicidio de rendimiento.

  •   
  • Definitivamente usa la concatenación   operador cuando puedas (legible)   especificar todo lo que debe ser   concatenado en una declaración. (Si tu   tener una variedad de cosas para   concatenar, considere llamar   String.Concat explícitamente - o   Cadena. Únete si necesitas un delimitador.)

  •   
  • No tengas miedo de romper los literales   en varios bits concatenados: el   El resultado será el mismo. Usted puede ayudar   legibilidad al romper un largo literal   en varias líneas, por ejemplo, con   sin dañar el rendimiento.

  •   
  • Si necesita los resultados intermedios   de la concatenación de algo   aparte de alimentar la próxima iteración   de concatenación, StringBuilder no es   Te voy a ayudar. Por ejemplo, si   construyes un nombre completo desde un primer   nombre y apellido, y luego agregue un   tercera pieza de información (la   apodo, tal vez) hasta el final, podrás   solo se beneficia al usar StringBuilder   si no necesita el (nombre +   apellido) cadena para otro propósito   (como lo hacemos en el ejemplo que crea   un objeto Persona).

  •   
  • Si solo tiene algunas concatenaciones   hacer, y realmente quieres hacerlas   en declaraciones separadas, no   Realmente importa en qué dirección vayas. Cual   manera es más eficiente dependerá de   la cantidad de concatenaciones los tamaños   de cadena involucrada, y en qué orden   están concatenados. Si realmente   cree que ese código es un   cuello de botella de rendimiento, perfil o   compararlo en ambos sentidos.

  •   

System.String es un objeto inmutable; significa que siempre que modifique su contenido, asignará una nueva cadena y esto lleva tiempo (¿y memoria?). Con StringBuilder, modifica el contenido real del objeto sin asignar uno nuevo.

Entonces use StringBuilder cuando necesite hacer muchas modificaciones en la cadena.

No realmente ... deberías usar StringBuilder si concatenas cadenas grandes o tienes muchas concatenaciones, como en un bucle.

No hay una respuesta definitiva, solo reglas generales. Mis propias reglas personales son más o menos así:

  • Si concatena en un bucle, use siempre un StringBuilder .
  • Si las cadenas son grandes, use siempre un StringBuilder .
  • Si el código de concatenación es ordenado y legible en la pantalla, entonces probablemente esté bien.
    Si no es así, use un StringBuilder .

Parafraseando

  

Entonces contarás hasta tres, ni más ni menos. Tres serán el número que contarás, y el número de la cuenta será tres. No contarás cuatro, ni contarás dos, excepto que luego pasarás a tres. Una vez que se alcanza el número tres, siendo el tercer número, entonces lanza tu granada de mano sagrada de Antioquía

Generalmente uso el generador de cadenas para cualquier bloque de código que resulte en la concatenación de tres o más cadenas.

  • Si concatena cadenas en un bucle, debería considerar usar StringBuilder en lugar de cadenas regulares
  • En caso de que sea una concatenación única, es posible que no vea la diferencia en el tiempo de ejecución en absoluto

Aquí hay una aplicación de prueba simple para demostrar el punto:

class Program
{
    static void Main(string[] args)
    {
        const int testLength = 30000;
        var StartTime = DateTime.Now;

        //TEST 1 - String
        StartTime = DateTime.Now;
        String tString = "test string";
        for (int i = 0; i < testLength; i++)
        {
            tString += i.ToString();
        }
        Console.WriteLine((DateTime.Now - StartTime).TotalMilliseconds.ToString());
        //result: 2000 ms

        //TEST 2 - StringBuilder
        StartTime = DateTime.Now;
        StringBuilder tSB = new StringBuilder("test string");
        for (int i = 0; i < testLength; i++)
        {
            tSB.Append(i.ToString());
        }
        Console.WriteLine((DateTime.Now - StartTime).TotalMilliseconds.ToString());
        //result: 4 ms

        Console.ReadLine();
    }
}

Resultados :

  • 30'000 iteraciones

    • Cadena - 2000 ms
    • StringBuilder - 4 ms
  • 1000 iteraciones

    • Cadena - 2 ms
    • StringBuilder - 1 ms
  • 500 iteraciones

    • Cadena - 0 ms
    • StringBuilder - 0 ms
  

Pero si quiero concatenar 2 cadenas, entonces supongo que es mejor y más rápido hacerlo sin StringBuilder. ¿Es esto correcto?

Sí Pero lo que es más importante, es mucho más legible usar una String de vainilla en tales situaciones. Usarlo en un bucle, por otro lado, tiene sentido y también puede ser tan legible como la concatenación.

Sería cuidadoso con las reglas generales que citan números específicos de concatenación como un umbral. Usarlo en bucles (y solo bucles) es probablemente igual de útil, más fácil de recordar y tiene más sentido.

Mientras pueda escribir físicamente el número de concatenaciones (a + b + c ...) no debería hacer una gran diferencia. N al cuadrado (en N = 10) es una desaceleración de 100X, que no debería ser tan malo.

El gran problema es cuando estás concatenando cientos de cadenas. Con N = 100, obtienes una desaceleración de 10000X veces. Lo cual es bastante malo.

No creo que haya una línea muy fina entre cuándo usarlo o cuándo no. A menos que, por supuesto, alguien realice algunas pruebas exhaustivas para salir con las condiciones doradas.

Para mí, no usaré StringBuilder si solo concatenamos 2 cadenas enormes. Si hay un bucle con un recuento indeterminado, es probable que lo haga, incluso si el bucle puede ser un recuento pequeño.

Una sola concatenación no vale la pena usar un StringBuilder. Por lo general, he usado 5 concatenaciones como regla general.

La clase StringBuilder proporciona al desarrollador un conjunto de métodos que permiten la manipulación de una cadena mutable de caracteres, que se puede usar cuando desee modificar una cadena sin crear un nuevo objeto, eliminando así el problema de la sobrecarga o el cuello de botella de la concatenación de cadenas normal.

Usar la clase StringBuilder puede aumentar el rendimiento al concatenar muchas cadenas juntas en un bucle.

La siguiente es una lista de algunas operaciones que se pueden realizar para manipular una cadena usando la clase StringBuilder en .NET

Agregar : agrega información al final del StringBuilder actual.

AppendFormat : reemplaza un especificador de formato pasado en una cadena con texto formateado.

Insertar : inserta una cadena u objeto en el índice especificado del StringBuilder actual.

Eliminar : elimina un número específico de caracteres del StringBuilder actual.

Reemplazar : reemplaza un carácter especificado en un índice específico.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top