編譯和重複使用
更新:2007 年 11 月
只要了解規則運算式引擎如何編譯運算式,以及了解如何快取規則運算式,您就可以使大量使用規則運算式的應用程式達到最佳效能。本主題討論編譯及快取。
編譯的規則運算式
根據預設,規則運算式引擎會將規則運算式編譯為內部指令的序列 (Sequence) (這些是不同於 Microsoft Intermediate Language (MSIL) 的高階程式碼)。當引擎執行規則運算式時,它將會解譯內部程式碼。
如果 Regex 物件是以 RegexOptions.Compiled 選項所建構,它會將規則運算式編譯成明確的 MSIL 程式碼,而非高階的規則運算式內部指令。這允許 .NET Framework 的 Just-in-Time (JIT) 編譯器 (Compiler) 將運算式轉換為原生機器碼以達到較高效能。
然而,產生的 MSIL 不能卸載。卸載程式碼的唯一方式就是要卸載整個應用程式定義域 (亦即,要卸載您應用程式的全部程式碼)。實際上,一旦規則運算式以 RegexOptions.Compiled 選項編譯之後,.NET Framework 絕不會釋放已編譯運算式所使用的資源,即使規則運算式是由 Regex 物件所建立,且物件本身被釋放並被記憶體回收。
您必須小心限制以 RegexOptions.Compiled 選項編譯的不同規則運算式數目,以避免消耗太多資源。如果應用程式必須使用大量或未限制數目的規則運算式,應該要解譯而不是編譯各個運算式。但是,如果要重複使用少數規則運算式,應該使用 RegexOptions.Compiled 編譯以獲得較高的效能。另外一種方式是使用預先編譯好的規則運算式。您可以使用 CompileToAssembly 方法,將所有運算式編譯成可重複使用的 DLL。這麼做便不需要在執行階段時進行編譯,而且仍然可以享有已編譯好規則運算式的速度。
規則運算式快取
為了提升效能,規則運算式引擎維護整個應用程式的已編譯規則運算式之快取。這個快取會儲存只有在靜態方法呼叫中使用的規則運算式模式 (不會快取提供給執行個體方法的規則運算式模式)。這避免在每次使用它時,還要重新剖析運算式為高階位元組程式碼。
規則運算式的快取上限,是由 static (在 Visual Basic 中為 Shared) Regex.CacheSize 屬性值所決定。根據預設,規則運算式引擎會快取最多 15 個已編譯的規則運算式。如果編譯的規則運算式數目超出快取的大小,就會捨棄最近最少使用的規則運算式,並快取新的規則運算式。
重要事項: |
---|
.NET Framework 2.0 版快取規則運算式的方式與 .NET Framework 1.0 和 1.1 版差異極大。.NET Framework 1.0 和 1.1 會快取所有的規則運算式,包括靜態方法呼叫和執行個體方法呼叫中所使用的規則運算式。快取會自動展開以儲存新的規則運算式。在 .NET Framework 2.0 中,只有靜態方法呼叫中所使用的規則運算式才會快取。根據預設,會快取最後 15 個規則運算式,但您可以設定 CacheSize 屬性的值以調整快取的大小。 |
您的應用程式可以透過下列其中一種方式,利用預先編譯的規則運算式:
使用 Regex 物件的靜態方法,定義規則運算式。如果您使用其他靜態方法呼叫中已定義的規則運算式模式,規則運算式引擎就會從快取中擷取這個規則運算式模式。如果沒有,則引擎會編譯規則運算式並新增至快取。
重複使用現有的 Regex 物件,只要需要物件的規則運算式模式就可以。
由於物件具現化及規則運算式編譯的負荷之關係,建立並迅速終結多個 Regex 物件是非常耗費資源的處理序。對於使用大量不同規則運算式的應用程式,您可以使用靜態 Regex 方法的呼叫,或增加規則運算式快取的大小,以達到最佳效能。