字符串拼接用“+”还是 StringBuilder?别再凭感觉写了

发布时间:2026/5/24 19:58:21

字符串拼接用“+”还是 StringBuilder?别再凭感觉写了 问题拼接字符串到底用哪个先问个实在的问题你在代码里怎么拼接字符串很多兄弟可能是这么写的string str Hello World; //当然这里只是举个例子也有的会在循环里这么干string result ;for (int i 0; i 1000; i){ result i.ToString(); // 循环拼接}然后有一天你听说了StringBuilder据说拼接性能更好。于是你开始纠结到底该用“”还是StringBuilder网上说法五花八门有的说“”慢成狗有的说编译器会优化根本不用操心。今天咱们就把这事掰扯清楚以后别再凭感觉写了。结论看场景别迷信一句话总结少量、固定次数的拼接直接用“”代码简洁编译器还会帮你优化。大量、循环内的拼接尤其是次数不确定时务必用StringBuilder否则性能可能崩盘。特殊场景如拼接集合、格式化考虑用string.Concat、string.Join或字符串插值它们底层已经做了优化。下面展开聊聊为什么。扩展从内存到原理一次讲透1. 字符串的“不可变性”是罪魁祸首C#里的字符串是引用类型而且是不可变的。什么意思就是你一旦创建了一个字符串它就定型了内容不能再改。当你试图“修改”它时其实是创建了一个全新的字符串对象原来的那个等着被垃圾回收。比如string s Hello;s s World;第二行执行时先在内存里创建一个新字符串Hello World然后把s指向它原来的Hello就成了没人要的孤儿等着GC来收。这种设计有好处线程安全、哈希缓存等但拼接时就成了性能杀手。2. “”拼接的真相分情况讨论情况A编译期就能确定的拼接string str Hello World;这种代码在编译时编译器直接把它优化成了Hello World生成的IL里只有一个字符串。所以运行时没有任何拼接开销放心用。情况B拼接中包含变量string name 刚子;string msg Hello, name !;这种编译器会把它转成string.Concat调用比如string msg string.Concat(Hello, , name,!);string.Concat内部会根据参数数量一次性计算出最终字符串长度然后分配内存把各部分拷贝进去。一次拼接一次分配效率其实不错。所以这种少量“”拼接完全没问题。情况C循环内反复拼接string result ;for (int i 0; i 10000; i){ result i.ToString();}这里每循环一次都会产生一个新的字符串而且一次比一次大。比如第1次长度1分配1次第2次长度2新分配拷贝之前的结果和新的字符第3次长度3再分配拷贝……这样总共分配了10000次字符串拷贝的总字符数大约是12...10000 ≈ 5000万次时间复杂度O(n²)数据量大时直接卡死。3. StringBuilder 为什么快StringBuilder内部维护了一个可变的字符数组char[]。当你 Append 时它会直接往数组里写空间不够了就自动扩容通常是翻倍。所有追加操作都在同一个数组里进行只有最后调用ToString()时才真正创建一次字符串。所以上面的循环用StringBuilder改写StringBuilder sb new StringBuilder();for (int i 0; i 10000; i){ sb.Append(i.ToString());}string result sb.ToString();扩容次数大约 log₂(10000) ≈ 14次假设初始容量16字符拷贝总量约10000次远小于“”的5000万次时间复杂度O(n)性能天壤之别。4. 来点实测数据我写了个简单测试环境.NET 6, Release模式各执行10万次拼接方式10次拼接1000次拼接10万次拼接循环内1ms15ms爆炸几秒StringBuilder1ms1ms8ms注意“”在小数量时差距不大但一旦数量上去直接崩盘。5. 其他拼接方式也得拎清楚string.Concat前面说了编译器会把多个“”优化成Concat。如果自己手动拼接一组已知的对象用Concat比循环“”强。string.Join拼接集合时最强string csv string.Join(,, numbers); // numbers是Listint内部也是用StringBuilder实现的比自己手写循环高效。字符串插值$...string msg $Hello, {name}! You are {age} years old.;编译后也是string.Format或者在某些情况下转成Concat。它简洁明了适合格式化场景但如果插值数量很多且频繁调用注意string.Format内部也有开销解析格式字符串、参数装箱等。不过日常用没问题。6. 最佳实践总结原则1能用一句话写完的拼接直接用“”编译器会优化。原则2循环内拼接尤其次数不确定时无脑用StringBuilder。原则3拼接集合用string.Join。原则4格式化用字符串插值或string.Format但避免在热点代码中频繁使用带复杂格式的插值。原则5如果提前能预估最终长度给StringBuilder预设容量new StringBuilder(预期长度)减少扩容。7. 面试官追问StringBuilder就一定比“”快吗不一定。如果只是两三个字符串拼接用“”编译成Concat可能比创建StringBuilder对象开销还小。毕竟new对象也有成本。所以“少量固定次数”时“”更优。另外如果你用的是.NET Core 2.1string.Create方法允许你直接操作字符数组实现最高效的拼接但那是高阶玩法日常用不上。总结字符串拼接这事看起来小但用错了地方真能把程序拖垮。别再凭感觉了记住三个关键词少量用“”、循环用Builder、集合用Join。写出性能好的代码从选对拼接方式开始。我是码农刚子本人擅长 .NET 后台、小程序、商城定制开发有需求可私信。如果觉得本文对你有帮助欢迎收藏、转发、关注让更多小伙伴少走弯路#字符串拼接 #StringBuilder #dotNet #csharp- - 看完本文有收获请转发分享给更多人 推荐关注「CSharp精选营」提升编程技能 精选推荐 点击标题可跳转使用 C# 实现23种常见的设计模式 DeepSeek本地部署指南打造你的专属AI伙伴C# WinForms 实现打印监听组件一个基于 .NET 开源、简易、轻量级的进销存管理系统ASP.NET Core Blazor简介和快速入门一基础篇ZR.Admin.NET为.NET开发者打造的效率利器一站式企业级后台开源框架ML.NET 快速入门与实践教程机器学习框架OpenClaw现象级爆红AI智能体的“事实标准”如何改变我们的开发方式.NET面试经典三问什么是.NET、.NET Framework、.NET Core?及相关引申问题 建群声明本着技术在于分享方便大家交流学习的初心特此建立【CSharp技术交流群】热烈欢迎各位进群交流学习编程心得也希望进群的大佬能不吝分享自己遇到的技术问题和经验。 扫码入群 长按识别二维码 添加微信好友备注“入群” 点赞和在看就是最大的支持❤️

相关新闻