您好,登錄后才能下訂單哦!
本篇內容介紹了“C#提高StringBuilder操作性能優化的方法是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
在 .NET 中,String 對象是不可改變的。每次使用 System.String 類中的方法之一時,都要在內存中創建一個新的字符串對象,這就需要為該新對象分配新的空間。
在需要對字符串執行重復修改的情況下,與創建新的 String 對象相關的系統開銷可能會非常昂貴。如果要修改字符串而不創建新的對象,則可以使用 System.Text.StringBuilder 類。例如,當在一個循環中將許多字符串連接在一起時,使用 StringBuilder 類可以提升性能。
BenchmarkDotNet是一款強力的.NET性能基準測試庫,為每個被測試的方法提供了孤立的環境。使用BenchmarkDotnet, 程序員可以很容易的編寫各種性能測試方法,并可以避免許多常見的坑。
本篇文章中,我們將利用 BenchmarkDotNet 為我們的 StringBuilder 操作進行基準測試。
要使用本篇文章提供的代碼示例,你的系統中應該安裝有 Visual Studio 2019 或者以上版本。
首先讓我們在 Visual Studio中 創建一個 .NET Core 控制臺應用程序項目。假設你的系統中已經安裝了 Visual Studio 2019,請按照下面的步驟創建一個新的 .NET Core 控制臺應用程序項目。
1. 啟動 Visual Studio IDE。
2. 點擊 "創建新項目"。
3. 在 "創建新項目 "窗口中,從顯示的模板列表中選擇 "控制臺應用程序(.NET核心)"。
4. 點擊 "下一步"。
5. 在接下來顯示的 "配置你的新項目 "窗口中,指定新項目的名稱和位置。
6. 點擊創建。
這將在 Visual Studio 2019 中創建一個新的 .NET Core 控制臺應用程序項目。我們將在本文的后續章節中使用這個項目來處理 StringBuilder。
要使用 BenchmarkDotNet,你必須安裝 BenchmarkDotNet 軟件包。你可以通過 Visual Studio 2019 IDE 內的 NuGet 軟件包管理器,或在 NuGet 軟件包管理器控制臺執行以下命令來完成。
Install-Package BenchmarkDotNet
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
下面說明了兩種方法的性能差異。
正如你所看到的,使用 StringBuilderCache 追加字符串要快得多,需要的分配也少。
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 使用的內存明顯較少。
注意,在使用 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 方法中使用字符來追加字符。
下圖顯示了這兩種方法的基準測試結果。
StringBuilder 允許你設置容量以提高性能。如果你知道你要創建的字符串的大小,你可以相應地設置初始容量以大大減少內存分配。
你還可以通過使用一個可重復使用的 StringBuilder 對象池來避免分配來提高 StringBuilder 的性能。
最后,請注意,由于 StringBuilderCache是一個內部類,你需要將源代碼粘貼到你的項目中才能使用它。回顧一下,在C#中你只能在同一個程序集或庫中使用一個內部類。
因此,我們的程序文件不能僅僅通過引用 StringBuilderCache 所在的庫來訪問 StringBuilderCache 類。
這就是為什么我們把 StringBuilderCache 類的源代碼復制到我們的程序文件中,也就是Program.cs文件。
“C#提高StringBuilder操作性能優化的方法是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。