垃圾回收器(GC)雖高效,但堆積物件配置與回收仍比堆疊操作昂貴。頻繁配置短暫參考型別會拖垮效能。掌握三大技巧,減輕 GC 壓力:
反例:OnPaint 每次建立相同 Font 物件。
// 差:每次 Paint 事件配置新 Font
using (Font f = new Font("Arial", 10f)) { ... }
正例:建立一次,重複使用。
// 好:唯讀成員,建構時初始化
private readonly Font _font = new Font("Arial", 10f);
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawString(DateTime.Now.ToString(), _font, Brushes.Black, new PointF(0,0));
}
實作 IDisposable 的成員提升為欄位時,擁有者類別也應實作 IDisposable(參見原則 18)。
Brushes.Black 採惰性單例模式:全程序僅建立一個黑色筆刷,首次使用時建立,後續直接重用。
private static Brush _blackBrush;
public static Brush Black
{
get
{
if (_blackBrush == null) _blackBrush = new SolidBrush(Color.Black);
return _blackBrush;
}
}
框架以此模式提供常用顏色、筆刷、筆等,未使用的資源永不建立。
字串串接 msg += ... 每次產生新字串,舊字串成垃圾:
// 低效:產生 4 個垃圾字串
string msg = "Hello, ";
msg += user.Name;
msg += ". Today is ";
msg += DateTime.Now.ToString();
改用 string.Format 或 StringBuilder:
// 好:單次配置
string msg = string.Format("Hello, {0}. Today is {1}", user.Name, DateTime.Now);
// 複雜情境:StringBuilder
var sb = new StringBuilder("Hello, ");
sb.Append(user.Name);
sb.Append(". Today is ");
sb.Append(DateTime.Now);
string final = sb.ToString();
StringBuilder 為可變緩衝區,完成後產出不可變字串。此模式適用於所有「多步驟建構不可變物件」情境(參見原則 7)。
StringBuilder、自訂 Builder)。