wpf(windows presentation foundation)是微軟推出的基於windows的使用者介面框架,執行在 .net framework 3.0及以上版本。wpf是基於directx引擎的,支援gpu硬體加速,在不支援硬體加速時也可以使用軟體繪製。儘管wpf有諸多優點,有時我們還是會遇到效能問題,比如介面卡頓,記憶體洩漏等等。針對wpf程式的效能優化是乙個寬泛的問題,本文是對我們這段時間以來所作工作的乙個總結。
相同的程式在不同的硬體上執行,會有不同的表現。對渲染能力影響比較大的硬體特性為:
在程式開發過程中制定一些**規範,可以讓我們避免一些效能問題的坑。
1.讓 visualtree 盡量簡單
在螢幕上繪製圖形時,每個元素的布局被呼叫兩次(measure & arrange)。布局過程是乙個數學密集型的過程,子元素的數量越多,需要的計算次數就越多。
2.虛擬化你的 itemcontrols
itemscontrols往往會增加 visualtree 的深度,如果沒有虛擬化會頻繁地建立和銷毀元素。使用virtualizingstackpanel作為宿主,並設定 virtualizationmode=recycling 以便重用元素的容器。
3.盡可能使用 staticresources
dynamicresources 會建立乙個臨時表示式並推遲對資源的查詢,當真正需要資源值時才去請求,其查詢方式和執行時查詢相同,這會對效能產生影響。
4.通過 brushes 設定透明度
如果使用 brush 來填充元素,那麼最好設定 brush 的透明度而不是設定 element 的透明度。當修改 element 的透明度時會導致wpf重繪。
5.避免使用 run 來設定text屬性
6.streamgeometry物件比pathgeometry更輕量級
streamgeometry在處理多個pathgeometry物件時進行了優化,消耗更小的記憶體,有更高的效能表現。
7.使用縮小尺寸的影象
如果程式需要顯示更小的縮圖,那麼建立縮小尺寸的影象版本會提高效能。
8.bitmapscalingmode
預設情況下,wpf使用高質量的影象重採集演算法,會導致幀率下降和動畫斷斷續續。設定lowquality切換到速度優化演算法可以提高效能。
9.freeze freezables
可凍結物件是一種特殊型別的物件,具有兩種狀態:未凍結和已凍結。比如 brush,geometry,凍結物件可以提高效能並減少記憶體消耗。
10.修正繫結錯誤
繫結錯誤是wpf程式中最常見的效能問題原因,每次發生繫結錯誤都會執行一次 perf 命中並嘗試解決錯誤。
11.避免繫結到 label.content
把string繫結到 label.content時會導致較差的效能。每次資料變動時,舊的string物件會被丟棄並建立乙個新的string物件。可以替換為 textblock.text 屬性。
12.使用 ilist 作為 itemscontrols 資料來源
當繫結 ienumerable資料作為 itemscontrol資料來源時,wpf會重新包裝為 ilist型別。
13.ui執行緒只做簡單的事情
不要在ui執行緒上做耗時的動作,ui執行緒只用來更新介面。
14.降低動畫的幀率
通過設定storyboard.desiredframerate降低動畫的幀率。
15.記憶體洩漏
記憶體洩漏也會降低程式效能,這塊內容比較多,後面會單獨篇幅中介紹。
當我們的程式開發完成後仍然存在效能問題,這時就要用到效能分析工具來幫助我們分析應用程式的執行時行為,並確定可以應用的效能優化的型別。比較常用的工具有:
不同的軟體,使用方法和側重點會有區別,可以真實使用並分析總結一下。下面對 dottrace 做乙個簡單的介紹。
dottrace
執行程式,開啟dottrace,我們就可以把程序附加到dottrace上。執行一段時間,獲取執行時情況快照來分析具體耗時情況。
如果是除錯程式,還可以聯動**,非常的方便。找到耗時較長的**,我們就可以針對性的對某個方法進行優化。比如針對乙個通過反射動態獲取欄位的**塊,優化前後的對比如下:
比如乙個string.split()方法的優化:
string.split() 方法內部會自動轉換成 char 型別,如果能直接傳入 char 型別會減少方法的耗時。像上面對方法的優化還有很多,我們最好對照 dottrace 報表為每乙個耗時方法都去分析為什麼耗時?還可以怎麼優化?
ui執行緒
在上面的分析做完之後,我們發現有個視窗還是占用比較高的耗時和cpu。這是乙個第三方的圖表控制項 devexpress ,用來重新整理波動率影象。在嘗試優化使用方法後,還是決定自己封裝外掛程式進行影象的繪製。我們把影象上所用到的元素分類抽象出來:
使用dottrace來分析對比兩個控制項的效能:
devexpress擁有.net開發需要的平台控制項,包含600多個ui控制項、報表平台等一系列輔助工具,可為桌面、web和移動應用提供直觀的解決方案。記憶體洩漏
dotmemory 是乙個 .net 的記憶體分析工具,可以幫助你優化 .net 應用的記憶體使用,找出記憶體洩漏和其他的記憶體使用問題.
記憶體洩漏是乙個內容比較多的主題,我們會有另外一篇文章具體來總結這方面的工作。最簡單使用場景:
程式效能的優化是乙個長週期的工作,我們也會持續的進行。本次比較籠統的總結了我們這段時間以來的工作,希望對你有所幫助。
WPF 效能優化 14 點
建立漂亮 ui 時需要關注應用程式的效能,wpf 尤其如此。以下是從 ms 文件中總結出的一些關鍵的效能優化點,實際編寫中可備參考。1 建立邏輯樹時,盡量考慮從父結點到子結點的順序構建。因為當邏輯樹的乙個結點發生變化時 比如新增或刪除 它的父結點和所有的子結點都會激發 invalidation。程式...
WPF效能優化點 出自《 》
在建立漂亮 ui的同時,我們還需要關注應用程式的效能,wpf尤其如此。下面從 ms的文件中總結出了一些有用的效能優化點。在實際編寫的過程中,可以參考。這個 post 非完全原創,是根據一些文件總結出來的。1 建立邏輯樹的時候,盡量考慮從父結點到子結點的順序構建。因為當邏輯樹的乙個結點發生變化時 比如...
閒話WPF之二六(WPF效能優化點)
在建立漂亮ui的同時,我們還需要關注應用程式的效能,wpf尤其如此。下面從ms的文件中總結出了一些有用的效能優化點。在實際編寫的過程中,可以參考。這個post非完全原創,是根據一些文件總結出來的。1 建立邏輯樹的時候,盡量考慮從父結點到子結點的順序構建。因為當邏輯樹的乙個結點發生變化時 比如新增或刪...