HOW TO:改善效能
更新:2007 年 11 月
下列程式設計作法可以節省記憶體,並改善裝置應用程式的效能。
若要利用 Windows Form 和圖形節省記憶體
在提供方法的控制項上使用 BeginUpdate 和 EndUpdate 方法,例如,ComboBox、ListBox、ListView、ToolStripComboBox 及 TreeView。
在重新調整控制項位置時使用 SuspendLayout 和 ResumeLayout 方法。
使用 Show() 方法之前,請先在背景 (Background) 載入其他表單,並以資料填入 (Populate) 控制項。
限制事件處理程式碼只能執行基本工作,讓暫止的處理序可以繼續執行。
請在處置訂閱者物件前,先使用減法指派運算子取消訂閱其事件。如需詳細資訊,請參閱 HOW TO:訂閱及取消訂閱事件 (C# 程式設計手冊)。未正確取消訂閱所產生的問題和記憶體遺漏相類以。
使用幕後點陣圖。如需範例,請參閱 HOW TO:在螢幕外繪製影像。
覆寫控制項上的 OnKeyDown、OnKeyPress 及 OnKeyUp 方法,而不要加入按鍵事件處理常式。
若要利用資料和字串節省記憶體
請避免使用列舉型別的 ToString 方法,因為它在搜尋中繼資料表時會影響效能。
避免 OutOfMemoryException 錯誤。當沒有足夠的記憶體可配置給內部用途或新物件執行實體時,Common Language Runtime 會擲回此例外狀況。若要避免此例外狀況,請避免設計會使用 64 KB 或更多記憶體之大型方法的程式。
請移除 System.SR.dll,其中含有例外狀況對話方塊的錯誤訊息字串。您可以在沒有這個檔案的情況下部署應用程式,以節省記憶體。如果檔案已經存在,.NET Compact Framework 會動態載入包含在 System.SR.dll 中的錯誤字串。
如果裝置上沒有此 .dll 檔案,所有的例外狀況都會包含「無法載入資源組件」的訊息。然而在開發期間,將 System.SR.dll 的參考加入至 Visual Studio 專案會很有用,如此您就會看到有意義的例外狀況。
字串是不可變動的,因此,每當您修改字串時,都會建立新的 String 物件。在建構將會經常修改的字串時,請考慮使用 StringBuilder。
如果您知道 DateTime 序列化 (Serialization) 所使用的確切格式,請對 DateTime 使用 ParseExact 方法。否則,DateTime 剖析器 (Parser) 將會循序嘗試套用數種文化特性特定的格式。
限制開啟 SqlCeCommand 物件的數目,並在完成時處置 (Dispose) 這些物件。
若要在與機器碼相互操作時節省記憶體
請在平台叫用作業中使用 Blittable 型別,該型別在 Managed 和 Unmanaged 記憶體中都具有通用的表示,例如 Int32 或 IntPtr。透過傳址 (By Reference) 方式傳遞大於 32 位元的 Blittable 實值型別,會比使用傳值 (By Value) 的方式更迅速。如需 Blittable 型別的詳細資訊,請參閱 .NET Compact Framework Blittable 型別。
請在函式簽章 (Signature) 中使用引數的 InAttribute 和 OutAttribute 屬性,以減少不必要的封送處理 (Marshaling)。
請使用 Marshal 類別中的方法,以手動方式在 IntPtr 和 Managed 物件之間進行轉換,例如 PtrToStructure、PtrToStringBSTR、GetObjectForNativeVariant 及 GetObjectForIUnknown。
請使用 Prelink 和 PrelinkAll 方法,讓支援機器碼至 Managed 呼叫的 Stub 可以進行 JIT 編譯。
如果您要原生 COM 物件如同一般情況傳回 S_FALSE,或傳回其他非 S_OK HRESULT 值,請將 PreserveSig 欄位設定為 true,並使 Managed 簽章符合原生簽章。如此,在執行階段將 COM 呼叫上的 HRESULT 值轉譯為例外狀況時,即可避免必要的 try/catch 區塊發生額外負荷。
請盡可能在一次平台叫用呼叫中完成工作,而不要使用多次呼叫。
若要在集合中節省記憶體
如果集合是以陣列為基礎,請使用索引子 (Indexer)。
由於動態調整大小可能會大幅地增加過多儲存體,因此,在可能的情況下請盡量指定集合的大小。
請使用泛型集合,以避免 Boxing 和 Unboxing 實值型別發生額外負荷。定義屬於自己的最佳化集合,便可以達到最佳的效能。
若要在 XML 中節省記憶體
請使用 XmlTextReader 和 XmlTextWriter,而不要使用 XmlDocument,因為後者會用掉更多記憶體。
請指定 XmlReaderSettings 和 XmlWriterSettings 的設定以改善效能。如果適用的話,IgnoreWhitespace 和 IgnoreComments 屬性值也可以顯著改善效能。
請使用 UTF-8、ASCII 及 UTF-16 字元編碼方式,這些比 ANSI 和 Windows 字碼頁編碼方式還快。
請避免使用結構描述進行剖析,因為這樣會需要額外的驗證工作。
在填入 DataSet 時請避免下列各項:
下列方針有助於改善使用 XML 還原序列化 (Deserialization) 時的效能:
由於每個字元都必須進行驗證,請將項目和屬性名稱盡量保持簡短。
以屬性資料為基礎的 XML,會比以項目資料為基礎的 XML 還快。
請適時使用 XmlNodeReader.Skip 方法。
當效能成為第一優先考量時,請使用二進位序列化。
讓每個型別使用一個 XmlSerializer 執行個體來進行 XML 序列化,以減少搜尋中繼資料的時間。
由於序列化大量 XML 可能會用盡記憶體,請考慮使用 BinaryReader 和 BinaryWriter,改為建立自訂的二進位序列化機制。
若要在使用 Web 服務時節省記憶體
請在讀取和寫入 DataSet 時使用 DiffGram。如需詳細資訊,請參閱 DiffGrams (ADO.NET)。
請將遠端 DataSet 及它的結構描述儲存至裝置,做為 XML。
由於第一次呼叫比後續的呼叫緩慢,請在啟動顯示畫面進行簡單的 Web 服務方法呼叫。
請小心處理網路和資料錯誤。
在某些情況下,先將 DataSet 手動序列化為 XML 字串之後再進行 Web 服務呼叫,可以產生更佳的效能。
若要在進階程式設計中節省記憶體
非同步處理大型作業。
避免虛擬呼叫。比起靜態或執行個體呼叫,.NET Compact Framework 執行階段虛擬呼叫大約慢了 30%。由於資源有限,.NET Compact Framework 不會使用 Vtable,因此必須往返類別和介面階層架構才能呼叫方法,而這是非常耗用資源的作業。.NET Compact Framework 會維護已解析之虛擬呼叫的快取,因此在多數情況下,並不需要重新解譯呼叫。
請盡可能使用欄位而非屬性。
請在定義實值型別時覆寫 GetHashCode 和 Equals 方法。如果沒有覆寫這兩個方法,執行階段便會在基底 ValueType 類別中使用這些方法的通用版本。
Use reflection with caution.對於未具現化 (Instantiated) 的類別,為了檢查目的而使用反映,可能會影響應用程式中具現化物件的效能。
請確定 Managed 資源具有完整型別名稱,並且在 RESX 檔案中也是正確的。這些資源必須具備正確版本和 PublicKeyToken 欄位。為不當指定的型別尋找最適當的替代型別,將會影響效能。
請注意,在某些情況下,從檔案直接讀取應用程式資料可能已經足夠,並且會比使用 ResourceManager 更有效率。ResourceManager 可能會在找出資源二進位檔之前,先探查檔案系統中的多個位置,以找出最相符的附屬組件。請針對工作使用適當的工具。
請參閱
概念
.NET Compact Framework 中的裝置記憶體管理
.NET Compact Framework HOW TO 主題