2011-07-29 8 views
5

Por lo tanto, soy principalmente un desarrollador C# y Java, pero supongo que esta pregunta podría pertenecer a cualquier lenguaje de programación que use StringBuilder o alguna derivada de los mismos.Uso de múltiples constructores de cadenas para una cadena

Está bien, así que es más o menos común saber que concatenar incluso un pequeño número de cadenas puede ser una gran causa de muerte (aunque incluso eso es discutible). Mi pregunta es si alguien tiene conocimiento de los efectos de rendimiento de usar un generador de cadenas dentro de un generador de cadenas. Para aclarar lo que quiero decir con eso, permítanme incluir algún código ficticio que debería ayudar a ilustrar mi punto.

También me doy cuenta de que, naturalmente, hay un golpe de rendimiento llamando a varias instancias de StringBuilder, pero no creo que lo llamaría lo suficiente como para causar problemas de rendimiento real. (Este supuesto también puede estar equivocado opiniones sobre ese sería útil también)

public string StringToGet() 
{ 
    StringBuilder sb = new StringBuilder("Some Text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append(MethodThatCreatesAnotherString()); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append(MethodThatCreatesAnotherString()); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append(MethodThatCreatesAnotherString()); 
    //etc 

    return sb.toString(); 

} 

private string MethodThatCreatesAnotherString() 
{ 
    StringBuilder sb = new StringBuilder("Other text"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 

    return sb.ToString(); 
} 

La lógica me dice que esto no debería ser un problema, pero algo acerca de este enfoque no parece que mirar bien para mí . ¿Alguien puede arrojar algo de luz sobre las siguientes preguntas

  1. ¿Crea esto un significativamente mayor impacto en el rendimiento que simplemente no usando métodos adicionales y el uso de una sola StringBuilder
  2. Es la práctica razonablemente aceptable.

Cualquier sitio en esto sería muy apreciado.

+0

Esta pregunta merece más crédito de lo que está recibiendo. Definitivamente hay aplicaciones para este tipo de algoritmo. – Panzercrisis

Respuesta

9

Normalmente, si el número de concatenaciones de cadenas alineadas es más de 5, es mejor usar StringBuilder. Si tiene control sobre los métodos que a su vez crean una cadena, ¿por qué no considera pasar su StringBuilder en el método?

public void MethodThatCreatesAnotherString(StringBuilder sb) 
{ 
    // code that appends to StringBuilder 
} 

lo tanto, cuando es el momento de llamar a esa función, se pasa en su StringBuilder actual, y que no pierda un impacto en el rendimiento, pero es a expensas de la ofuscación potencial.

Dicho esto, a menos que esté ingresando en los cientos o miles de estas operaciones, no me preocuparé por una optimización prematura aquí. Su golpe de rendimiento principal es tener que hacerlo dos veces (es decir, agregar las cadenas dentro del método y luego anexar la cadena completa), pero aún no tomará el golpe de rendimiento hasta el punto de usar la concatenación +.

Editar: Un ejemplo clarificador de cómo usarlo:

string SomeMethodCreatingAString() 
{ 
    StringBuilder sb = new StringBuilder(); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    MethodThatCreatesAnotherString(sb); 
    // more text 
    return sb.ToString(); 
} 

Por lo tanto, no siempre append esa cadena desde el segundo método, sólo tiene que utilizar el mismo StringBuilder dentro de ese método. Espero que tenga sentido.

+0

Ese es un muy buen punto drharris y @Scott Munro que soy alguien avergonzado de decir que no consideré. Parece que bajo este método el generador de cadenas original simplemente ve el Append (SomeMethod()) como otra cadena que básicamente respondería a mi pregunta. – pat8719

+0

Me di cuenta de que no daba instrucciones reales sobre cómo llamarlo. Espero que haya entendido la intención, pero en caso de que alguien más se presente, agregué un ejemplo. No te preocupes por no considerarlo; esta es una decisión de diseño como todo lo demás, y no siempre es la mejor manera de hacerlo. Al devolver 'void', el método está ocultando lo que realmente hace, que a veces no es la mejor manera de hacerlo. A veces preferiría tomar los milisegundos adicionales de rendimiento para obtener un código más claro. – drharris

+0

Entendí tu intención, pero gracias de todos modos. Basado en la opinión general de todas estas respuestas, creo, por el bien del código limpio, sería mejor evitar un retorno "vacío" en el método, especialmente teniendo en cuenta el hecho de que el rendimiento es probablemente mínimo. . – pat8719

4

No estoy seguro acerca de las implicaciones de rendimiento, pero cambiar la firma de su MethodThatCreatesAnotherString método para aceptar un StringBuilder eliminaría la necesidad de varias instancias de StringBuilder.

4

Como http://www.codinghorror.com/blog/2009/01/the-sad-tragedy-of-micro-optimization-theater.html muestra que la diferencia entre las diferentes formas de concatenar cadenas es realmente muy pequeña hasta que se llega a un número realmente grande de concatenaciones.

Por lo tanto, a menos que ya sepa que tiene un problema de rendimiento con este código, entonces creo que está bien. Realmente solo obtiene 3 inits adicionales de constructor de cadenas y 3 asignaciones de cadenas adicionales en su ejemplo.

A la larga, debe intentar hacer lo que es más simple y solo preocuparse por complicadas micro optimizaciones si está seguro de que las necesita y las pruebas las descubren.

+0

+1 Sin duda, este es un punto justo, ya que tienden a usar StringBuilder de manera instintiva, por así decirlo, mis preguntas estaban realmente dirigidas a asegurar que no hubiera algo absolutamente incorrecto con el uso de StringBuilders 'incrustados'. Gracias por compartir el artículo. – pat8719

Cuestiones relacionadas