在編寫基於.Net架構的應用程序,尤其是分布式時,我們常常極為關注應用程序的執行效率。如果掌握了如何編寫高效率的代碼,就能大幅度地提高應用程序的執行速度,並有助於減少應用程序的瓶頸(bottlenecks)。
18.4.1 撤消
我們知道,類object是.Net架構中的其它一個類的基類。類object是在System中定義的,它並沒有聲明析構函數,而是定義了一個保護類型的成員方法Finalize。
如果.Net的運行時垃圾收集器認為一個對象可以安全從內存中移出時,垃圾收集器就調用該對象的撤消方法Finalize,把對象移出內存,釋放占用的系統資源。我們應該把對一些重要性能的考慮牢記在腦海裡。
如果你有C++的開發背景,你也許會傾向於采用對象的析構函數來撤消對象。不過當你在.Net環境下編程,你就不能再試圖依靠析構函數來執行對象的撤消。
對象的撤消方法Finalize會對程序的性能產生下列不良影響:
自己擁有撤消方法的對象在釋放資源時將耗費更長的時間。
垃圾收集器並不按照一定的順序來撤消對象,也並不保證每一個對象的撤消方法都能被正確的調用。
如果本應該撤消的對象引用了另一個暫時還不能撤消的對象,這個對象也不能撤消。
如果同時有大量的對象在等待撤消,這將會極為耗費系統資源,並降低系統性能。
每個需要清除的對象都必須執行撤消。為了優化性能,在必須使用Finalize方法時,你可以重載一個Close方法,當你需要清除某個對象時,你就可以調用Close方法,從而強迫垃圾收集器調用撤消方法,把該對象設為null。調用GC.SupressFinalize()方法(GC是System中提供的一個類),可以為你的代碼中的元數據設置一個標記,告訴運行時GC不要撤消這個類。這樣,你就可以在對象已沒有用處時立即動手釋放它。
下面的代碼展示了如何設計一個重載Close方法的類:
public class MyClass{ public override void close(){ GC.SupressFinalize(this) } protected override void Finalize(){ Close(); } }
18.4.2 事務
當可操控的代碼必須要和示操控的代碼進行交互時,事務(transition)就發生了。這通常出現在當你需要平台調用服務(Platform Invocation Services,PInvoke)來訪問未操控的動態鏈接庫的靜態指針入口,或者是訪問COM提供的其它方法時。
每一次事務都會帶來少量的開銷,據估計每調用一次事務大約要執行10到40條指令。因此,最好的編程習慣是在代碼中盡量少調用事務。如果情況必須,那就謹慎地使用事務。在使用API函數時,應盡可能地每次執行多個動作,而不是重復調用,但每次只執行少量動作。