|
|
|
|
|
在我之前的文章中,我展示了一些C#性能優(yōu)化的技巧,比較了一些代碼的執(zhí)行速度,你可以參考一下以下的文章:
在本文中,我將繼續(xù)介紹C#的技巧,展示各種代碼片段的內(nèi)存消耗。
技巧 1:使用StringBuilder比String消耗內(nèi)存少
在下面的示例中,我們將看到 String
和 StringBuilder
的內(nèi)存分配圖。以下是我對 String
和 StringBuilder
執(zhí)行相同操作的代碼。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading;
using System.Globalization;
using System.Data.SqlClient;
namespace Test1
{
public class Test1
{
string Name ;
public void Process()
{
Name = Name + "A";
}
}
public class Test2
{
StringBuilder sb = new StringBuilder();
public void Process()
{
sb.Append("A");
}
}
class Program
{
static void Main(string[] args)
{
Test1 t = new Test1();
t.Process();
Test2 t1 = new Test2();
t1.Process();
}
}
}
這是代碼執(zhí)行的內(nèi)存分配圖。
在這里,我們從主函數(shù)調(diào)用兩個函數(shù) Process()
, 盡管它們具有相同的名稱,但它們屬于不同的類,并且 Test1.Process
正在處理 String
數(shù)據(jù),而 Test2.Process()
正在處理 StringBuilder
數(shù)據(jù)。在分配圖中,我們可以看到 String
處理函數(shù)消耗了 Main()
函數(shù) 94% 的資源,而處理 StringBuilder
的 Test2 類中的 Process()
僅消耗了 Main()
函數(shù)資源的 21%。
因此,得出的結(jié)論是“當(dāng)你想多次連接字符串時,始終使用 StringBuilder
”。
技巧 2:字符串格式 VS 字符串連接
在第一點(diǎn)中,我展示了 String
如何比 StringBuilder
消耗更多的資源。在這一點(diǎn)上,我將比較格式化輸出與字符串連接。在第一個函數(shù)中,我使用格式規(guī)范來打印格式化輸出(基本上我是在連接一個字符串)。在另一個函數(shù)中,我使用 (+) 運(yùn)算符連接一個字符串,如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading;
using System.Globalization;
using System.Data.SqlClient;
namespace Test1
{
class Test
{
public void Format()
{
int a = 100;
Console.WriteLine("{0}AND{1}", a, a);
}
public void Concatination()
{
int a = 100;
Console.WriteLine(a + "AND" +a );
}
}
class Program
{
static void Main(string[] args)
{
Test t = new Test();
t.Format();
t.Concatination();
Console.ReadLine();
}
}
}
在內(nèi)存分配中,我們將看到:
使用 format
打印字符串的函數(shù)消耗了 57% 的資源,而簡單連接兩個字符串的函數(shù)消耗了主函數(shù) 30% 的資源。
所以我們可以清楚地看到如果我們使用字符串連接而不是輸出格式,我們可以節(jié)省我們的系統(tǒng)資源。
技巧 3:使用靜態(tài)類或函數(shù)不消化內(nèi)存
如果可能,請嘗試實(shí)現(xiàn)靜態(tài)函數(shù),因?yàn)殪o態(tài)對象(函數(shù)和數(shù)據(jù))不屬于特定類的任何對象,所以如果你不創(chuàng)建一個對象那么就不存在內(nèi)存消耗的問題。下面我將展示一個靜態(tài)函數(shù)和靜態(tài)類的示例。并查看 IL 代碼。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading;
using System.Globalization;
using System.Data.SqlClient;
namespace Test1
{
public static class mySclass
{
public static void Print()
{
Console.Write("Hello");
}
}
public class myNclass
{
public static void Print()
{
Console.Write("Hello");
}
}
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 1000; i++)
{
mySclass.Print();
myNclass.Print();
}
}
}
}
IL 代碼在左側(cè),右側(cè)是 CLR 分析器獲取的前幾個內(nèi)存消耗類。由于空間消耗,我無法顯示 CLR 分析器的完整屏幕截圖。但是相信我(哈哈)靜態(tài)類或函數(shù)是沒有內(nèi)存分配的。
由此,我們可以得出的結(jié)論是“如果可能,請嘗試創(chuàng)建一個靜態(tài)函數(shù)并使用類名調(diào)用,而不是通過對象名調(diào)用通用函數(shù)”。
總結(jié)
本文介紹了幾個消耗內(nèi)存較少的C#技巧,因?yàn)閮?nèi)存消耗對程序運(yùn)行速度影響很大,所以這些技巧能幫助我們優(yōu)化C#的性能。
相關(guān)文章