文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C#提高StringBuilder操作性能优化的方法是什么

2023-06-25 16:16

关注

本篇内容介绍了“C#提高StringBuilder操作性能优化的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

在 .NET 中,String 对象是不可改变的。每次使用 System.String 类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间。

在需要对字符串执行重复修改的情况下,与创建新的 String 对象相关的系统开销可能会非常昂贵。如果要修改字符串而不创建新的对象,则可以使用 System.Text.StringBuilder 类。例如,当在一个循环中将许多字符串连接在一起时,使用 StringBuilder 类可以提升性能。

BenchmarkDotNet是一款强力的.NET性能基准测试库,为每个被测试的方法提供了孤立的环境。使用BenchmarkDotnet, 程序员可以很容易的编写各种性能测试方法,并可以避免许多常见的坑。

本篇文章中,我们将利用 BenchmarkDotNet 为我们的 StringBuilder 操作进行基准测试。

要使用本篇文章提供的代码示例,你的系统中应该安装有 Visual Studio 2019 或者以上版本。

1. 在Visual Studio中创建一个控制台应用程序项目

首先让我们在 Visual Studio中 创建一个 .NET Core 控制台应用程序项目。假设你的系统中已经安装了 Visual Studio 2019,请按照下面的步骤创建一个新的 .NET Core 控制台应用程序项目。

这将在 Visual Studio 2019 中创建一个新的 .NET Core 控制台应用程序项目。我们将在本文的后续章节中使用这个项目来处理 StringBuilder。

2. 安装 BenchmarkDotNet NuGet包

要使用 BenchmarkDotNet,你必须安装 BenchmarkDotNet 软件包。你可以通过 Visual Studio 2019 IDE 内的 NuGet 软件包管理器,或在 NuGet 软件包管理器控制台执行以下命令来完成。

Install-Package BenchmarkDotNet

3. 使用 StringBuilderCache 来减少分配

StringBuilderCache 是一个内部类,在 .NET 和 .NET Core 中可用。每当你需要创建多个 StringBuilder 的实例时,你可以使用 StringBuilderCache 来大大减少分配的成本。

StringBuilderCache 的工作原理是缓存一个 StringBuilder 实例,然后在需要一个新的 StringBuilder 实例时重新使用它。这减少了分配,因为你只需要在内存中拥有一个 StringBuilder 实例。

让我们用一些代码来说明这一点。在 Program.cs 文件中创建一个名为 StringBuilderBenchmarkDemo 的类。创建一个名为 AppendStringUsingStringBuilder 的方法,代码如下。

public string AppendStringUsingStringBuilder(){    var stringBuilder = new StringBuilder();    stringBuilder.Append("First String");    stringBuilder.Append("Second String");    stringBuilder.Append("Third String");    return stringBuilder.ToString();}

上面的代码片段显示了如何使用 StringBuilder 对象来追加字符串。接下来创建一个名为 AppendStringUsingStringBuilderCache 的方法,代码如下。

public string AppendStringUsingStringBuilderCache(){    var stringBuilder = StringBuilderCache.Acquire();    stringBuilder.Append("First String");    stringBuilder.Append("Second String");    stringBuilder.Append("Third String");    return StringBuilderCache.GetStringAndRelease(stringBuilder);}

上面的代码片段说明了如何使用 StringBuilderCache 类的 Acquire 方法创建一个 StringBuilder 实例,然后用它来追加字符串。

下面是 StringBuilderBenchmarkDemo 类的完整源代码供你参考。

[MemoryDiagnoser]public class StringBuilderBenchmarkDemo { [Benchmark]      public string AppendStringUsingStringBuilder() {            var stringBuilder = new StringBuilder();            stringBuilder.Append("First String");            stringBuilder.Append("Second String");            stringBuilder.Append("Third String");            return stringBuilder.ToString();      }      [Benchmark]      public string AppendStringUsingStringBuilderCache() {            var stringBuilder = StringBuilderCache.Acquire();            stringBuilder.Append("First String");            stringBuilder.Append("Second String");            stringBuilder.Append("Third String");            return StringBuilderCache.GetStringAndRelease(stringBuilder);      }}

你现在必须使用 BenchmarkRunner 类来指定初始起点。这是一种通知 BenchmarkDotNet 在指定的类上运行基准的方式。

用以下代码替换 Main 方法的默认源代码。

static void Main(string[] args){    var summary = BenchmarkRunner.Run<StringBuilderBenchmarkDemo>();}

现在在 Release 模式下编译你的项目,并在命令行使用以下命令运行基准测试。

dotnet run -p StringBuilderPerfDemo.csproj -c Release

下面说明了两种方法的性能差异。

C#提高StringBuilder操作性能优化的方法是什么

正如你所看到的,使用 StringBuilderCache 追加字符串要快得多,需要的分配也少。

4. 使用 StringBuilder.AppendJoin 而不是 String.Join

String 对象是不可变的,所以修改一个 String 对象需要创建一个新的 String 对象。因此,在连接字符串时,你应该使用 StringBuilder.AppendJoin 方法,而不是String.Join,以减少分配,提高性能。

下面的代码列表说明了如何使用 String.Join 和 StringBuilder.AppendJoin 方法来组装一个长字符串。

[Benchmark]public string UsingStringJoin() {            var list = new List < string > {                        "A",                        "B", "C", "D", "E"            };            var stringBuilder = new StringBuilder();            for (int i = 0; i < 10000; i++) {                        stringBuilder.Append(string.Join(' ', list));            }            return stringBuilder.ToString();}[Benchmark]public string UsingAppendJoin() {            var list = new List < string > {                        "A",                        "B", "C", "D", "E"            };            var stringBuilder = new StringBuilder();            for (int i = 0; i < 10000; i++) {                        stringBuilder.AppendJoin(' ', list);            }            return stringBuilder.ToString();}

下图显示了这两种方法的基准测试结果。

请注意,对于这个操作,这两种方法的速度很接近,但 StringBuilder.AppendJoin 使用的内存明显较少。

C#提高StringBuilder操作性能优化的方法是什么

5. 使用 StringBuilder 追加单个字符

注意,在使用 StringBuilder 时,如果需要追加单个字符,应该使用 Append(char) 而不是 Append(String)。

请考虑以下两个方法。

[Benchmark]public string AppendStringUsingString() {      var stringBuilder = new StringBuilder();      for (int i = 0; i < 1000; i++) {            stringBuilder.Append("a");            stringBuilder.Append("b");            stringBuilder.Append("c");      }      return stringBuilder.ToString();}[Benchmark]public string AppendStringUsingChar() {      var stringBuilder = new StringBuilder();      for (int i = 0; i < 1000; i++) {            stringBuilder.Append('a');            stringBuilder.Append('b');            stringBuilder.Append('c');      }      return stringBuilder.ToString();}

从名字中就可以看出,AppendStringUsingString 方法说明了如何使用一个字符串作为 Append 方法的参数来追加字符串。

AppendStringUsingChar 方法说明了你如何在 Append 方法中使用字符来追加字符。

下图显示了这两种方法的基准测试结果。

C#提高StringBuilder操作性能优化的方法是什么

6. 其他 StringBuilder 优化方法

StringBuilder 允许你设置容量以提高性能。如果你知道你要创建的字符串的大小,你可以相应地设置初始容量以大大减少内存分配。

你还可以通过使用一个可重复使用的 StringBuilder 对象池来避免分配来提高 StringBuilder 的性能。

最后,请注意,由于 StringBuilderCache是一个内部类,你需要将源代码粘贴到你的项目中才能使用它。回顾一下,在C#中你只能在同一个程序集或库中使用一个内部类。

因此,我们的程序文件不能仅仅通过引用 StringBuilderCache 所在的库来访问 StringBuilderCache 类。

这就是为什么我们把 StringBuilderCache 类的源代码复制到我们的程序文件中,也就是Program.cs文件。

“C#提高StringBuilder操作性能优化的方法是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯