string拼接在循环中慢是因为其不可变性导致每次+操作都创建新对象,引发大量内存分配和gc压力;应改用预估容量初始化的stringbuilder,避免频繁扩容,并在循环外统一tostring。

为什么 string 拼接在循环里很慢
因为 string 在 C# 中是不可变类型,每次用 + 或 += 拼接,都会创建一个新字符串对象,旧字符串被丢弃。循环 10000 次?就分配 10000 个临时字符串,GC 压力大,内存占用高,性能直线下滑。
StringBuilder 什么时候该用、怎么初始化
适合多次追加(尤其是循环内拼接)、最终才生成完整字符串的场景。关键不是“用了就快”,而是“用对了才快”:
- 初始化时尽量预估容量:
new StringBuilder(1024),避免内部数组反复扩容(每次扩容约 1.5 倍,涉及数组复制) - 不要用默认无参构造——它初始容量只有 16,小字符串还行,一进循环就频繁扩容
- 如果拼接内容长度高度不确定,宁可略高估(比如设为预期长度的 1.2 倍),也别让它反复
Array.Copy
StringBuilder 的常用写法和避坑点
别只记得 Append(),这些细节直接影响效率和正确性:
- 用
AppendLine()代替Append("\n"),它自动适配当前平台换行符(\r\n或\n) - 拼接数字或布尔值,直接
Append(123)或Append(true),别先.ToString()——StringBuilder内部有专用重载,省掉装箱和临时字符串 - 避免在循环中反复调用
ToString(),它会创建新字符串;等全部Append完再调一次即可 - 不需要复用时,及时丢弃引用,让 GC 回收;若需清空重用,用
Clear()而不是new新实例(减少分配)
StringBuilder sb = new StringBuilder(2048);
for (int i = 0; i < list.Count; i++)
{
sb.Append("Item #").Append(i).Append(": ").Append(list[i]).AppendLine();
}
string result = sb.ToString(); // 只在这里调用一次简单拼接别硬套 StringBuilder
两三个字符串拼接,比如 "Hello " + name + "!",编译器会自动优化成 string.Concat,比 StringBuilder 还快。滥用反而增加对象创建和方法调用开销。
真正要警惕的是:嵌套循环、日志批量组装、XML/JSON 片段生成、SQL 拼接这类“动态长度 + 高频追加”的场景——那里才是 StringBuilder 发挥价值的地方。










