2011-05-29 72 views
19

可能重复:
What's the best string concatenation method using C#?做字符串连接快于C#

嗨,

我有一个代码段像这样在数据的大量内容是从读文件并检查每个位置的某个值并将其串起来。

该字符串连接需要大量的时间和处理能力。有没有一种方法可以减少执行时间?

重要:在阅读内容文件语法不正确只需要给一个想法

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 – 2011-05-29 04:55:16

+10

-1:将来,提供一个更接近于你实际正在做的事情(实际上是C#)的代码示例将有助于答复者写出比超过一般的'使用'StringBuilder'”。例如,你是如何阅读文件的,你是否真的在检查每个字符,你串联的字符串是否真的是单个字符等。 – 2011-05-29 05:37:23

回答

28

使用StringBuilder而不是字符串连接。

一个StringBuilder对象维护一个缓冲区以适应新数据的连接。如果空间可用,新数据将附加到缓冲区的末尾;否则,将分配一个新的更大的缓冲区,将原始缓冲区中的数据复制到新缓冲区中,然后将新数据附加到新缓冲区中。

字符串相反是不可变的,每次连接时它会创建一个新对象并丢弃旧对象,这是非常低效的。

另外,如果您知道结果将会很大,您可能需要提前为StringBuilder设置高容量。这将减少缓冲区重新分配的次数。

以你的伪代码将是这样的:

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

非常感谢你的回答 – Sudantha 2011-05-29 05:00:39

+0

实际上是投票计数! – Sudantha 2011-05-29 05:08:57

+3

@Sudantha:因为听起来好像你是StringBuilder的新手,可能值得一提的是,只有在进行“多次”连接时才有用。 – Niklas 2011-05-29 06:15:43

7

使用StringBuilder相反,将执行好得多 - 使用字符串创建一个新的字符串,它会导致很多的环路内的各时间开销/垃圾收集,使用您在循环外部创建的单个StringBuilder可以避免这种情况。

19

System.Text.StringBuilder是您希望用于循环中字符串连接操作的类型。这将会更有效率。在每次迭代期间在对象上使用.Append(value)

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

感谢您的答案我认为你是正确的答案给亚历克斯:) – Sudantha 2011-05-29 05:09:39

6

使用StringBuilder。

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

使用StringBuilder,字符串在.net中是不可变的,意思是任何连接都会生成字符串的副本。

Using the StringBuilder Class (MSDN)

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

当你读通过字节文件字节,它可以花费太长的时间。我建议你在循环中读取一个字节块(例如1024或2048)。然后,在你读过的块中,使用正则表达式来匹配你的角色,特别是如果你有一个非常大的文件。

示例代码将是这样的:

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(); 
} 

你会称这个为

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