C# 中的字符串创建如何避免分配?

小老鼠
发布: 2025-10-07 09:46:02
原创
736人浏览过
优先使用Span<char>和ReadOnlySpan<char>避免字符串分配,通过stackalloc在栈上处理短字符串,用String.Create预分配生成字符串,减少隐式拼接,降低GC压力。

c# 中的字符串创建如何避免分配?

在 C# 中,字符串是不可变引用类型,每次修改都会创建新实例,导致内存分配。要避免不必要的字符串分配,关键在于减少临时字符串的生成,优先使用结构化方式处理文本数据。

使用 Span<char> 和 stackalloc

对于短字符串操作,可使用 Span<char>上分配字符数组,避免堆分配:

  • stackalloc 在栈上创建固定大小的字符缓冲区
  • 通过 new string(Span<char>) 构造函数直接生成字符串(仅在必要时)
  • 适合已知长度且较小的文本处理(如格式化数字、小段拼接)

例如:

unsafe
{
    char* buffer = stackalloc char[256];
    // 填充数据到 buffer
    string result = new string(buffer, 0, length);
}
登录后复制

使用 ReadOnlySpan<char> 处理子串

传统 Substring() 会分配新字符串。改用 ReadOnlySpan<char> 可以切片而不分配:

  • 从原始字符串获取 span 切片,共享内存
  • 适用于解析、分词等中间处理阶段
  • 仅当最终需要字符串时才调用 .ToString()

示例:

阿里妈妈·创意中心
阿里妈妈·创意中心

阿里妈妈营销创意中心

阿里妈妈·创意中心0
查看详情 阿里妈妈·创意中心
string input = "hello world";
ReadOnlySpan<char> span = input.AsSpan();
ReadOnlySpan<char> word = span.Slice(0, 5); // 不分配
// 后续处理可用 word 比较、查找等
登录后复制

使用 String.Create 预分配构造

当你必须创建新字符串但想控制分配时机,可用 String.Create

  • 提前指定长度,避免多次扩容
  • 通过 Action<char*, object> 委托填充内容
  • 适用于高性能场景下的确定长度字符串生成

示例:

string result = String.Create(10, 123, (chars, value) =>
{
    // 直接写入 chars 指针
    value.ToString().AsSpan().CopyTo(chars);
});
登录后复制

避免隐式字符串拼接

使用 StringBuilder 仍可能产生中间分配。更优选择包括:

  • string.Concat(params object[]) 替代多个 + 操作(如果参数少且固定)
  • 对固定模板用 ReadOnlySpan 拼接后一次性转字符串
  • 日志等场景考虑结构化输出,延迟字符串化

基本上就这些。核心思路是:能不用字符串就先用 span,必须创建时尽量明确生命周期和大小,减少中间临时对象。配合 ref struct 和栈分配,能显著降低 GC 压力。

以上就是C# 中的字符串创建如何避免分配?的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号