• C# StringBuilder 的使用


    目录

    一、为什么用 StringBuilder

    二、测试效率

    1.字符串连接方式

    2.StringBuilder 方式

    三、StringBuilder 常用方法

    1.Append

    2.Insert

    3.Remove

    4.Replace

    结束


    一、为什么用 StringBuilder

    字符串一旦创建就不可修改大小,每次使用System.String类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间。在需要对字符串执行重复修改的情况下,与创建新的String对象相关的系统开销可能会非常昂贵。

    所以对字符串添加或删除操作不频繁的话,就几个固定的string累加的时候就不需要StringBuilder了,毕竟StringBuilder的初始化也是需要时间的。对字符串添加或删除操作比较频繁的话那就用StringBuilder。

    使用C#字符串连接方式 

    1. String a1 = "abc";  //分配固定的内存大小
    2. a1 += "def";  //创建新的内存分配a1,代价比较昂贵

    使用 StringBuilder 方式

    1. StringBuilder sb = new StringBuilder(20);  //指定分配大小
    2. sb.Append('abc');  //分配到堆区
    3. sb.Append('def');  //不会被销毁,而是直接追加到后面。

    二、测试效率

    看了官方说的那么好,那我们就来测试下效率怎么样,以5万次循环来统计字符串连接方式,和StringBuilder方式那个耗时更高

    1.字符串连接方式

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. namespace 计算1
    7. {
    8. class Program
    9. {
    10. static void Main(string[] args)
    11. {
    12. System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
    13. stopwatch.Start();
    14. string msg = string.Empty;
    15. for (int i = 0; i < 50000; i++)
    16. {
    17. msg += i.ToString();
    18. }
    19. //Console.WriteLine(msg);
    20. stopwatch.Stop();
    21. string res = string.Format("耗时:{0}分 {1}秒 {2}毫秒", stopwatch.Elapsed.Minutes, stopwatch.Elapsed.Seconds, stopwatch.Elapsed.Milliseconds);
    22. Console.WriteLine(res);
    23. Console.ReadKey();
    24. }
    25. }
    26. }

    效果:

     几次测试的时间

    耗时:0分 1秒 485毫秒
    耗时:0分 1秒 408毫秒
    耗时:0分 1秒 508毫秒

    2.StringBuilder 方式

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. namespace 计算1
    7. {
    8. class Program
    9. {
    10. static void Main(string[] args)
    11. {
    12. System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
    13. stopwatch.Start();
    14. StringBuilder sb = new StringBuilder(50000);
    15. for (int i = 0; i < 50000; i++)
    16. {
    17. sb.Append(i);
    18. }
    19. //Console.WriteLine(sb);
    20. stopwatch.Stop();
    21. string res = string.Format("耗时:{0}分 {1}秒 {2}毫秒", stopwatch.Elapsed.Minutes, stopwatch.Elapsed.Seconds, stopwatch.Elapsed.Milliseconds);
    22. Console.WriteLine(res);
    23. Console.ReadKey();
    24. }
    25. }
    26. }

    效果

    测试了好几次,运行的耗时都是5毫秒

    结果显而易见,StringBuilder 效率高了实在太多了,但是,这是字符串比较多的情况下,如果就写几个字符串的时候,意义不是特别大,当然了,即使在字符数量比较少的时候,StringBuilder 的效率依然是比字符串连接的方式高的,缺点就是必须先实例化,在字符比较少的情况下用起来不是特别方便。

    三、StringBuilder 常用方法

    1.Append

    向 StringBuilder 内追加字符串

    public StringBuilder Append(double value);

    这里存在多个函数重载,可以添加字符串,也可以添加数组,这里我就不过多介绍了

    参数 value 是 要添加的字符串

    实例:

    1. namespace 计算1
    2. {
    3. class Program
    4. {
    5. static void Main(string[] args)
    6. {
    7. StringBuilder sb = new StringBuilder();
    8. sb.Append("hello ");
    9. sb.Append("world");
    10. Console.WriteLine(sb);
    11. Console.ReadKey();
    12. }
    13. }
    14. }

    输出

    hello world

    2.Insert

    向 StringBuilder 内追加数据

    public StringBuilder Insert(int index, object value);

    这里有多个函数重载,我只复制了其中的一个

    第一个参数 index 是插入的位置索引

    第二个参数 value 是插入的内容

    实例:

    1. namespace 计算1
    2. {
    3. class Program
    4. {
    5. static void Main(string[] args)
    6. {
    7. StringBuilder sb = new StringBuilder();
    8. sb.Append("hello");
    9. sb.Append("world");
    10. sb.Insert(5, "_我是插入的字符_");
    11. Console.WriteLine(sb);
    12. Console.ReadKey();
    13. }
    14. }
    15. }

    输出

    hello_我是插入的字符_world

    3.Remove

    删除字符串

    public StringBuilder Remove(int startIndex, int length);

    第一个参数 startIndex 是删除字符的起始位置

    第二哥参数 length 是要删除的长度

    实例:

    1. namespace 计算1
    2. {
    3. class Program
    4. {
    5. static void Main(string[] args)
    6. {
    7. StringBuilder sb = new StringBuilder();
    8. sb.Append("hello");
    9. sb.Append("world");
    10. sb.Remove(5, sb.Length - 5);
    11. Console.WriteLine(sb);
    12. Console.ReadKey();
    13. }
    14. }
    15. }

    输出

    hello

    4.Replace

    替换字符串,这里有两个重载,下面我用两个案例来阐述。

    案例1

    将旧的字符串,替换新的字符串

    public StringBuilder Replace(char oldChar, char newChar);

    第一个参数 oldChar 是旧的字符串

    第二个参数 newChar 是你要替换的字符串

    1. namespace 计算1
    2. {
    3. class Program
    4. {
    5. static void Main(string[] args)
    6. {
    7. StringBuilder sb = new StringBuilder();
    8. sb.Append("hello");
    9. sb.Append("world");
    10. sb.Replace("hello", "HELLO_");
    11. Console.WriteLine(sb);
    12. Console.ReadKey();
    13. }
    14. }
    15. }

    输出

    HELLO_world

    案例2

    public StringBuilder Replace(char oldChar, char newChar, int startIndex, int count);

    第一个参数 oldChar 是旧的字符串

    第二个参数 newChar 是你要替换的字符串

    第三个参数 startIndex  子字符串开始的位置

    第四个参数 count 子字符串的长度

    结果:对此实例的引用,其中从 startIndex 到 startIndex + count -1 范围内的 oldChar 被 newChar 替换。

    这个重载我感觉多次一举,因为后面的 startindex 必须是正确的索引,如果位置不对,结果是不会替换的,而且 count 这个参数不对,也不会执行替换操作

    1. namespace 计算1
    2. {
    3. class Program
    4. {
    5. static void Main(string[] args)
    6. {
    7. StringBuilder sb = new StringBuilder();
    8. sb.Append("年轻人不讲武德,来骗,来偷袭,我一个69岁的老同志");
    9. sb.Replace("69", "79", 18, 2);
    10. Console.WriteLine(sb);
    11. Console.ReadKey();
    12. }
    13. }
    14. }

    输出

    年轻人不讲武德,来骗,来偷袭,我一个79岁的老同志

    结束

    如果这个帖子对你有用,欢迎 关注 + 点赞 + 留言,谢谢

    end

  • 相关阅读:
    SpringSecurity Oauth2实战 - 08 SpEL权限表达式源码分析及两种权限控制方式原理
    PHP伪协议详解
    【python】安装python 3.11
    最强大脑记忆曲线(9)——按错误频率排序待听写内容
    C语言基本结构:顺序、选择和循环
    【无标题】
    CVPR 2023 | UniMatch: 重新审视半监督语义分割中的强弱一致性
    【NR 物理资源】
    通俗解释进程与线程
    如何利用自动发现将现网的进程纳入到监控系统中?
  • 原文地址:https://blog.csdn.net/qq_38693757/article/details/126189267