翼度科技»论坛 编程开发 .net 查看内容

改一个对象类型,for循环耗时从3000毫秒下降到1毫秒

9

主题

9

帖子

27

积分

新手上路

Rank: 1

积分
27
 
概述:在C#中,字符串连接有两种实现方法:使用`+`运算符和使用`StringBuilder`。前者在每次连接时都会创建新的字符串对象,效率较低。后者通过内部管理字符数组,避免了频繁的内存分配和垃圾回收,因此性能更高。在处理大量字符串连接时,使用`StringBuilder`可以显著提高性能。这两种方法在功能上等价,但性能差异可达10倍或更多。 。
先上效果:
 
最近在和网友聊天时他问道:他做了一个生成代码的小工具,生成一个文件很快,但生成一个项目时就会很慢,找不到原因,让我帮分析一下是哪里的问题。能过性能分析工具和查看相关代码,发现他大量使用了字符串拼接,问题就出在这里了,下面来分析一下。
在C#中,字符串拼接时使用 string 和 StringBuilder 会导致性能差异的主要原因是,string 类型是不可变的,每次拼接都会创建一个新的字符串对象,而 StringBuilder 是可变的,可以在原始对象上进行操作,避免了创建新对象的开销。
下面分别演示使用 string 和 StringBuilder 进行字符串拼接的性能差异,并提供详细的实例源代码。
使用string和StringBuilder进行字符串拼接:
  1. public static class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         //循环50000次
  6.         int start = 50000;
  7.         //测试5次每以50000的数量增加
  8.         for (int i = 0; i < 5; i++)
  9.         {
  10.             //循环次数
  11.             int end = start + (start * i);
  12.             //测量执行时间(单位为毫秒)
  13.             var executionTimer = GetExecutionTimer(() =>
  14.             {
  15.                 //执行测试
  16.                 Test1(end);
  17.             });
  18.             //测量执行时间(单位为毫秒)
  19.             var executionTimer2 = GetExecutionTimer(() =>
  20.             {
  21.                 //执行测试
  22.                 Test2(end);
  23.             });
  24.             Console.WriteLine($"{(i + 1)}:循环{end}次,Test1用时:{executionTimer}毫秒,Test2用时:{executionTimer2}毫秒");
  25.             Console.WriteLine($"{(i + 1)}:Test2是Test1的{((double)executionTimer / executionTimer2)}倍");
  26.             Console.WriteLine();
  27.         }
  28.         Console.ReadKey();
  29.     }
  30.     /// <summary>
  31.     /// 测试方法1
  32.     /// </summary>
  33.     static void Test1(int end)
  34.     {
  35.         string result = "";
  36.         for (int i = 0; i < end; i++)
  37.         {
  38.             result += i.ToString();
  39.         }
  40.     }
  41.     /// <summary>
  42.     /// 测试方法2
  43.     /// </summary>
  44.     static void Test2(int end)
  45.     {
  46.         StringBuilder sb = new StringBuilder();
  47.         for (int i = 0; i < end; i++)
  48.         {
  49.             sb.Append(i);
  50.         }
  51.         string result = sb.ToString();
  52.     }
  53.     /// <summary>
  54.     /// 返回一个委托执行时间(通用)
  55.     /// </summary>
  56.     /// <param name="action">要执行的代码块</param>
  57.     /// <returns>代码块的执行时间(毫秒)</returns>
  58.     static long GetExecutionTimer(this Action action)
  59.     {
  60.         // 获取当前时间戳
  61.         var stopwatch = new Stopwatch();
  62.         stopwatch.Start();
  63.         // 执行传入的代码块
  64.         action();
  65.         // 停止计时
  66.         stopwatch.Stop();
  67.         // 返回执行时间
  68.         return stopwatch.ElapsedMilliseconds;
  69.     }
  70. }
复制代码
上述两个示例中,使用 string 拼接字符串时,每次循环都会创建一个新的字符串对象,而使用 StringBuilder 则会在原始对象上进行追加,避免了创建多个对象。在迭代次数较多时,StringBuilder 的性能明显优于直接使用 string。



来源:https://www.cnblogs.com/hanbing81868164/p/17977524
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具