C# += (plus equals) (Assignment by addition) 工作很慢,当字符串太长时?

Posted

技术标签:

【中文标题】C# += (plus equals) (Assignment by addition) 工作很慢,当字符串太长时?【英文标题】:C# += (plus equals) (Assignment by addition) working very slow, when string is too long? 【发布时间】:2010-12-17 10:02:52 【问题描述】:

我有一个 for 循环,我要做的就是这个。

forloop ( loop 7000 times)

x += 2000_char_long_string;

代码在这个 forloop 中持续了很长时间,可能超过 1 分钟。我该如何解决这个问题?

谢谢。

【问题讨论】:

在您的情况下,在 StringBuilder 初始化期间指定容量会有助于您的代码更快,并避免由于 StringBuilder 中的内存重新分配而产生的开销。请在下面查看我的答案。 StringBuilder 移动油漆罐! joelonsoftware.com/articles/fog0000000319.html 【参考方案1】:

使用StringBuilder。

StringBuilder sb = new StringBuilder();
for(int i=0; i< 200; i++)
   sb.append(longString);

return sb.ToString();

当你在字符串上使用+= 时,你会不断地创建新的字符串,并不断地定位越来越大的内存块。这就是为什么操作如此缓慢的原因。

【讨论】:

一个改进是也设置初始容量。如果要分配 7000 * 2000 个字符串,则将初始容量设置为 14000000 以避免重复增长缓冲区。【参考方案2】:

使用StringBuilder,作为@Kobi referenced,您仍然可以通过初始化它来提高性能。看来您可以提前确定string 的最终大小。

StringBuilder sb = new StringBuilder(7000*2000);
for(int i=0; i< 7000; i++)
   sb.append(2000_char_long_string);

return sb.ToString();

【讨论】:

请注意,即使您不确定确切的长度是多少,也请做出最佳猜测。过度猜测不会增加任何开销(除了内存),即使你猜测不足,你仍然会比以前分配更少。【参考方案3】:

字符串操作是不可变的。每次 stmt x += 2000_char_long_string; 都会创建一个新字符串;被执行。因此,正如 Kobi 所建议的,您应该使用 StringBuilder 类。

但是,在您的情况下,您应该在 StringBuilder 构造函数中指定容量。

这是因为如果不指定,StringBuilder在创建时默认容量为16。

一旦这个容量用完,它将创建一个新的连续内存位置,将 StringBuilder 的所有内容复制到新位置并将实例指向新位置。由于您已经知道最终字符串的大致大小(可能是 7000 * 2000),因此您可以相应地指定容量。

更多详情请查看我对StringBuilder and capacity?的回复。

【讨论】:

【参考方案4】:

您应该使用StringBuilder 类

【讨论】:

【参考方案5】:

C# 字符串对象是不可变的,每次更改内容时都会创建新对象并复制新内容。改用 StringBuilder,它是为了解决您面临的问题而提供的

【讨论】:

以上是关于C# += (plus equals) (Assignment by addition) 工作很慢,当字符串太长时?的主要内容,如果未能解决你的问题,请参考以下文章

C#中equal与==的区别

== 和 Equals() 之间的 C# 区别

C# 中基元的 == 和 Equals() 有啥区别?

C# Equals

C# 中 == 运算符和 Equals() 方法的区别?

C# == equals 本质理解