欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

提高C# StringBuilder操作性能優(yōu)化的方法

 更新時間:2021年11月19日 16:46:21   作者:編程寶庫  
本篇文章主要介紹使用C# StringBuilder 的項目實踐,用于減少內(nèi)存分配,提高字符串操作的性能。對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

本文探討使用C# StringBuilder 的最佳實踐,用于減少內(nèi)存分配,提高字符串操作的性能。

在 .NET 中,String 對象是不可改變的。每次使用 System.String 類中的方法之一時,都要在內(nèi)存中創(chuàng)建一個新的字符串對象,這就需要為該新對象分配新的空間。

在需要對字符串執(zhí)行重復修改的情況下,與創(chuàng)建新的 String 對象相關的系統(tǒng)開銷可能會非常昂貴。如果要修改字符串而不創(chuàng)建新的對象,則可以使用 System.Text.StringBuilder 類。例如,當在一個循環(huán)中將許多字符串連接在一起時,使用 StringBuilder 類可以提升性能。

BenchmarkDotNet是一款強力的.NET性能基準測試庫,為每個被測試的方法提供了孤立的環(huán)境。使用BenchmarkDotnet, 程序員可以很容易的編寫各種性能測試方法,并可以避免許多常見的坑。

本篇文章中,我們將利用 BenchmarkDotNet 為我們的 StringBuilder 操作進行基準測試。

要使用本篇文章提供的代碼示例,你的系統(tǒng)中應該安裝有 Visual Studio 2019 或者以上版本。

1. 在Visual Studio中創(chuàng)建一個控制臺應用程序項目

首先讓我們在 Visual Studio中 創(chuàng)建一個 .NET Core 控制臺應用程序項目。假設你的系統(tǒng)中已經(jīng)安裝了 Visual Studio 2019,請按照下面的步驟創(chuàng)建一個新的 .NET Core 控制臺應用程序項目。

  • 1. 啟動 Visual Studio IDE。
  • 2. 點擊 "創(chuàng)建新項目"。
  • 3. 在 "創(chuàng)建新項目 "窗口中,從顯示的模板列表中選擇 "控制臺應用程序(.NET核心)"。
  • 4. 點擊 "下一步"。
  • 5. 在接下來顯示的 "配置你的新項目 "窗口中,指定新項目的名稱和位置。
  • 6. 點擊創(chuàng)建。

這將在 Visual Studio 2019 中創(chuàng)建一個新的 .NET Core 控制臺應用程序項目。我們將在本文的后續(xù)章節(jié)中使用這個項目來處理 StringBuilder。

2. 安裝 BenchmarkDotNet NuGet包

要使用 BenchmarkDotNet,你必須安裝 BenchmarkDotNet 軟件包。你可以通過 Visual Studio 2019 IDE 內(nèi)的 NuGet 軟件包管理器,或在 NuGet 軟件包管理器控制臺執(zhí)行以下命令來完成。

Install-Package BenchmarkDotNet

3. 使用 StringBuilderCache 來減少分配

StringBuilderCache 是一個內(nèi)部類,在 .NET 和 .NET Core 中可用。每當你需要創(chuàng)建多個 StringBuilder 的實例時,你可以使用 StringBuilderCache 來大大減少分配的成本。

StringBuilderCache 的工作原理是緩存一個 StringBuilder 實例,然后在需要一個新的 StringBuilder 實例時重新使用它。這減少了分配,因為你只需要在內(nèi)存中擁有一個 StringBuilder 實例。

讓我們用一些代碼來說明這一點。在 Program.cs 文件中創(chuàng)建一個名為 StringBuilderBenchmarkDemo 的類。創(chuàng)建一個名為 AppendStringUsingStringBuilder 的方法,代碼如下。

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

上面的代碼片段顯示了如何使用 StringBuilder 對象來追加字符串。接下來創(chuàng)建一個名為 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 方法創(chuàng)建一個 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);
      }
}

你現(xiàn)在必須使用 BenchmarkRunner 類來指定初始起點。這是一種通知 BenchmarkDotNet 在指定的類上運行基準的方式。

用以下代碼替換 Main 方法的默認源代碼。

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

現(xiàn)在在 Release 模式下編譯你的項目,并在命令行使用以下命令運行基準測試。

dotnet run -p StringBuilderPerfDemo.csproj -c Release

下面說明了兩種方法的性能差異。

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

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

String 對象是不可變的,所以修改一個 String 對象需要創(chuàng)建一個新的 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();
}

下圖顯示了這兩種方法的基準測試結(jié)果。

請注意,對于這個操作,這兩種方法的速度很接近,但 StringBuilder.AppendJoin 使用的內(nèi)存明顯較少。

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 方法的參數(shù)來追加字符串。

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

下圖顯示了這兩種方法的基準測試結(jié)果。

6. 其他 StringBuilder 優(yōu)化方法

StringBuilder 允許你設置容量以提高性能。如果你知道你要創(chuàng)建的字符串的大小,你可以相應地設置初始容量以大大減少內(nèi)存分配。

你還可以通過使用一個可重復使用的 StringBuilder 對象池來避免分配來提高 StringBuilder 的性能。

最后,請注意,由于 StringBuilderCache是一個內(nèi)部類,你需要將源代碼粘貼到你的項目中才能使用它。回顧一下,在C#中你只能在同一個程序集或庫中使用一個內(nèi)部類。

因此,我們的程序文件不能僅僅通過引用 StringBuilderCache 所在的庫來訪問 StringBuilderCache 類。

這就是為什么我們把 StringBuilderCache 類的源代碼復制到我們的程序文件中,也就是Program.cs文件。

參考資料:

1. C#教程

2. C#編程技術

3. 編程寶庫

ASP.NET提高StringBuilder類操作性能就向你介紹到這里,希望對你有所幫助。

相關文章

  • 詳解C# 泛型中的數(shù)據(jù)類型判定與轉(zhuǎn)換

    詳解C# 泛型中的數(shù)據(jù)類型判定與轉(zhuǎn)換

    這篇文章主要介紹了C# 泛型中的數(shù)據(jù)類型判定與轉(zhuǎn)換,文中講解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-07-07
  • C#中嵌入SQLite數(shù)據(jù)庫的簡單方法

    C#中嵌入SQLite數(shù)據(jù)庫的簡單方法

    本文給大家介紹的是C#中嵌入SQLite數(shù)據(jù)庫的簡單方法,十分的方便也很實用,有需要的小伙伴可以參考下。
    2015-06-06
  • C#異常捕獲機制圖文詳解

    C#異常捕獲機制圖文詳解

    在本文中我們給大家分享了關于C#異常捕獲機制的相關知識點內(nèi)容,有興趣的朋友們學習下。
    2019-02-02
  • C#實現(xiàn)系統(tǒng)桌面右下角彈框

    C#實現(xiàn)系統(tǒng)桌面右下角彈框

    這篇文章主要為大家詳細介紹了C#如何實現(xiàn)系統(tǒng)桌面右下角彈框,文中的示例代碼講解詳細,對我們學習C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2023-01-01
  • C#文件斷點續(xù)傳實現(xiàn)方法

    C#文件斷點續(xù)傳實現(xiàn)方法

    這篇文章主要介紹了C#文件斷點續(xù)傳實現(xiàn)方法,涉及C#文件傳輸?shù)募记?具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • C#實現(xiàn)把彩色圖片灰度化代碼分享

    C#實現(xiàn)把彩色圖片灰度化代碼分享

    這篇文章主要介紹了C#實現(xiàn)把彩色圖片灰度化代碼分享,用在一些特殊場合中,需要的朋友可以參考下
    2014-08-08
  • C# XmlDocument操作XML案例詳解

    C# XmlDocument操作XML案例詳解

    這篇文章主要介紹了C# XmlDocument操作XML案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C# API中模型與它們的接口設計詳解

    C# API中模型與它們的接口設計詳解

    這篇文章主要給大家介紹了關于C# API中模型與它們的接口設計的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-06-06
  • C#中的協(xié)變與逆變小結(jié)

    C#中的協(xié)變與逆變小結(jié)

    這篇文章主要介紹了C#中的協(xié)變與逆變的相關知識,在泛型或委托中,如果不使用協(xié)變或逆變,那么泛型類型是一個固定類型,而使用協(xié)變或逆變的話,則泛型類型可以實現(xiàn)多態(tài)化,需要的朋友可以參考下
    2021-10-10
  • VMS中解協(xié)議常用方法備忘(小結(jié))

    VMS中解協(xié)議常用方法備忘(小結(jié))

    這篇文章主要介紹了VMS中解協(xié)議常用方法備忘(小結(jié)),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01

最新評論