2011-05-29 7 views
19

Duplicar posibles:
What's the best string concatenation method using C#?Hacer concatenación de cadenas más rápido en C#

Hola,

que tienen un fragmento de código como este donde un gran contenido de los datos se leen desde una archiva y revisa cada posición por algún valor y concatena una cadena.

Esta concatenación de cadenas requiere una gran cantidad de tiempo y potencia de procesamiento. ¿Hay un enfoque donde puedo reducir el tiempo de ejecución?

Importante: La lectura de sintaxis del archivo de contenido no es correcto sólo tiene que dar una idea

string x; 

while (var < File.Length) 
{ 
    if (File.Content[var] == "A") 
    { 
     x += 1;  
    } 
    else 
    { 
    x += 0; 
    } 
    var++; 
} 
+1

http://stackoverflow.com/questions/21078/whats-the-best-string- concatenation-method-using-c –

+10

-1: en el futuro, proporcionar un ejemplo de código que esté más cerca de lo que realmente está haciendo (y es realmente C#) ayudará a los respondedores a escribir mejores soluciones que el consenso generalizado de 'uso 'StringBuilder' '. Por ejemplo, cómo está realmente leyendo el archivo, si realmente está comprobando cada carácter, si las cadenas concatenadas son realmente caracteres únicos, etc. –

Respuesta

28

Uso StringBuilder en lugar de concatenaciones de cadenas.

Un objeto StringBuilder mantiene un búfer para acomodar la concatenación de datos nuevos. Se añaden nuevos datos al final del búfer si hay espacio disponible; de lo contrario, se asigna un nuevo búfer más grande, los datos del búfer original se copian en el nuevo búfer, y luego se añaden los nuevos datos al nuevo búfer.

Cadena por el contrario es inmutable, cada vez que concatenas crea un objeto nuevo y desecha los viejos, lo que es muy ineficiente.

Además, es posible que desee establecer una gran capacidad para StringBuilder por adelantado, si sabe que el resultado será enorme. Esto reducirá el número de reasignaciones de búfer.

Tomando su pseudo-código que se vería así:

StringBulder x = new StringBuilder(10000); // adjust capacity to your needs 

while (var < File.Length) 
{ 
    if(File.Content[var] == "A") 
     x.Append("1"); // or AppendLine, or AppendFormat 
    else 
     x.Append("2"); 
} 
+0

muchas gracias por la respuesta – Sudantha

+0

¡en realidad fue el conteo de votos! – Sudantha

+3

@Sudantha: como parece que eres nuevo en StringBuilder, vale la pena mencionar que solo es beneficioso cuando realizas "muchas" concatenaciones. – Niklas

7

Utilice un StringBuilder lugar, que llevará a cabo mucho mejor - el uso de cadenas se crea una nueva cadena cada vez dentro del bucle que hace que una gran cantidad de colección de sobrecarga/basura, utilizando un único StringBuilder que cree fuera del ciclo, puede evitarlo.

19

System.Text.StringBuilder es el tipo que desea utilizar para las operaciones de concatenación de cadenas en un bucle. Va a ser mucho más eficiente. Use .Append(value) en el objeto durante cada iteración.

StringBuilder builder = new StringBuilder(); 

// and inside your loop 
{ 
    if (blah) 
     builder.Append("1"); 
    else 
     builder.Append("0"); 
} 

string output = builder.ToString(); // use the final result 
+0

gracias por la respuesta, creo que está bien darle la respuesta correcta a Alex :) – Sudantha

6

Utilice un StringBuilder.

var sb = new StringBuilder(); 
sb.Append("abc"); 
sb.Append("def"); 
var str = sb.ToString(); 
7

Uso StringBuilder, las cadenas son inmutables en el sentido de que cada vez .net concatenación hace una copia de la cadena.

Using the StringBuilder Class (MSDN)

StringBuilder sb = new StringBuilder(); 
sb.Append("1") // like so 
1

Cuando se lee un byte a byte de archivos, puede tomar mucho tiempo. Le recomendaría que lea un bloque de bytes (por ejemplo, 1024 o 2048) en el ciclo. Luego, en el bloque que ha leído, use una expresión regular para que coincida con su personaje, especialmente si tiene un archivo extremadamente grande.

Código de ejemplo sería algo como esto:

private string GetFileData(string fileName, string matchChar) 
{ 
    StringBuilder x = new StringBuilder(); 
    int blockCount = 2048; 
    int offset = 0; 
    string pattern = matchChar; 
    int k = -1; 
    using (var sr = new System.IO.FileStream(fileName, System.IO.FileMode.Open)) 
    { 
     while ((sr.CanRead) && (k != 0)) 
     { 
      byte[] bt = new byte[blockCount]; 
      k = sr.Read(bt, 0, blockCount); 
      string so = System.Text.UTF8Encoding.UTF8.GetString(bt); 
      var m = new System.Text.RegularExpressions.Regex(pattern).Matches(so); 
      foreach (System.Text.RegularExpressions.Match item in m) 
      { 
       x.Append(item.Value); 
      } 
     } 
    } 
    return x.ToString(); 
} 

Se podría llamar a esto como

GetFileData(@"c:\matchtest.ono", "a"); 
Cuestiones relacionadas