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) 工作很慢,当字符串太长时?的主要内容,如果未能解决你的问题,请参考以下文章