使用dotTrace工具對.Net程序進行性能分析實戰

提起dotTrace不用多說,是個很經典的性能分析工具,可以分析windows form和asp.net 的application,它能夠快速分析、過濾、函數查找(快速定位function,並且導航)和查看源碼等等,具體的軟件使用操作這裡就不進行介紹了,感興趣的朋友可以網上查操作手冊或使用說明。

手頭有一款.Net桌面應用程序,每次啟動都很慢,準備使用這個工具分析一下,看怎麼改進啟動速度。

1、首先通過dotTrace啟動運行準備分析的程序exe文件


使用dotTrace工具對.Net程序進行性能分析實戰


2、點擊“Get Snapshot and wait”按鈕,獲取分析報告的快照。

3、一般情況,如果不考慮方法調用次數,我們通常分析Threads Tree就可以。


使用dotTrace工具對.Net程序進行性能分析實戰

如上圖:這裡顯示兩個線程,主線程總共花費17秒,線程10是一個後臺網絡遠程下載數據的線程,花費9秒(因為多線程並行執行的,目前需要著重分析主線程)。

因為快照中把每個執行的方法都列了出來,還有每個方法花費的時間。去掉系統本身花費的時間,然後去掉所使用平臺花費的時間,我們把重點放在自己應用程序所寫的代碼上。


使用dotTrace工具對.Net程序進行性能分析實戰


比如說這裡:InitializeCompent方法,花費了678毫秒的時間。這個方法是.net 框架提供的方法,我們一般沒有可優化的空間,進行分析會發現時間花在了WPF xaml文件裝載上了。不過從這裡也能看出WPF的性能確實不高。

分析啟動Run()方法的執行情況,發現下面這些方法花費時間較多,是可能有問題的方法。


使用dotTrace工具對.Net程序進行性能分析實戰

CreateShell方法

InitilizeModules方法

ConfigurationContainer方法

StartUpTomcat方法

LoadDBMySql方法

(一)、其中StartUpTomcat是調用命令行Shell執行一些批處理命令,LoadDBMysql是調用數據服務進行更新sql語句的操作,這兩個方法花費了1秒多時間。

可以新開後臺線程執行這兩個方法,這樣就能不影響主線程的時間。

代碼如下:

Task startUpTask = Task(() => StartUpTomcat());
startUpTask.ContinueWith(t => LoadDBMySql());
startUpTask.Start()

修改後分析報告,會多出一個後臺線程,執行這兩個方法。


使用dotTrace工具對.Net程序進行性能分析實戰


(二)、接下來分析createShell方法,因為用的Prism4.0基於WPF的框架,createShell由框架提供,還需要分析一下該方法具體執行步驟,單擊展開該方法的各個節點進行分析。

終於找到疑點了,有兩個方法花費了3秒鐘。如圖:


使用dotTrace工具對.Net程序進行性能分析實戰


有兩個初始化類的調用,一個是DataAccess類,另外一個是WorkDataSynacProxyService類。

DataAccess是IBatisNet的封裝,WorkDataSynacProxyService是數據同步的一個服務代理類。由於啟動時根本不需要執行數據庫的操作,可以把這部分代碼延遲執行,或者還是使用老辦法,後臺新開線程執行初始化數據庫的操作類,WorkDataSynacProxyService初始化代碼去掉,換成使用時在創建實例的方式。

上面兩點都完成以後,節約3秒鐘啟動時間。

(三)、接下來接著分析,InitilizeModules方法,這個方法有Prism框架提供,經過分析我們發現主要問題是從文件目錄中裝載模塊DLL文件太慢,GetExportedTypes方法,懷疑是因為使用反射導致的性能問題。


使用dotTrace工具對.Net程序進行性能分析實戰

因為Prism框架中支持幾種方式的分模塊開發和部署,DirectionModuleCatalog目錄的方式是最簡單的,同時也是效率最低的方式。不再使用DirectionModuleCatalog的方式加載模塊,可以採用配置文件,或代碼裝載的方式來提高這部分加載性能,或者乾脆實現代碼中預裝載,這樣可以大幅度提高模塊裝載速度。

(四)、最後是ConfigContainer方法,如下圖,分析發現兩個RegisterMap方法(應用於Domain對象和DTO對象進行轉換),使用反射來創建對象實例,總共花費了1.4秒時間。

新開後臺線程,把這兩部分代碼放到後臺線程執行。

代碼: var task = new Task(() => RegisterDomainAdapterMaps());
task.Start();

使用dotTrace工具對.Net程序進行性能分析實戰

到此為止此次性能分析算是基本完成了,一般來說我們著重觀察執行時間大於500毫秒的方法。

總的來說做性能分析首先需要明確性能瓶頸在哪裡,一般都是數據操縱(I/O)操作,網絡操作等。

明確是否代碼的質量有問題,也要看關注調用次數,是否某些方法調用次數過多,比如在循環中寫了不恰當的代碼等。

還有就是明確是否存在Block的代碼,比如:遠程網絡連接,文件I/O操作等。

使用緩存或者多線程,以提高性能。

總歸就是一句話,如果能準確的找到問題瓶頸,你的問題已經解決了一半。


分享到:


相關文章: