WPF官方發布第一個版本至今已經有10年了, 我們幾乎在同時也開始了XAML開發。即使經過多年打造,我們依舊嘗試提高:我們真的成功打造了高效靈活的控件嗎?我沒有在其他地方找到任何關于優秀的WPF表格性能比較的介紹,只有少量而年代久遠的現在已經不存在的控件的討論。這個新基準是一種嘗試,用來在一些市場相對流行的控件比較中發現我們的優勢和不足。
環境
這個基準創建于2016年6月,使用了下面Grid控件。(我們使用的最新試用版)
- System.Windows.Controls 下的DataGrid (PresentationFramework.dll的一部分)
- C1FlexGrid 4.4.0.20162.514 (ComponentOne WPF版)
- C1DataGrid 4.4.0.20162.514 (ComponentOne WPF版)
- XamDataGrid v16.1.16.1.20161.1000 (WPF Controls - Infragistics)
- GridControl v15.2.15.2.10.0 (WPF Controls | DevExpress)
- SfDataGrid 14.1400.0.41 (Syncfusion Essential Studio WPF版 )
- RadGridView 2016.2.503.40 (Telerik WPF Controls | UI WPF版)
- DataGridControl v5.9.5.9.16204.15420 (Xceed DataGrid for WPF)
這個基準運行于ENVY-23 All-in-One Desktop環境,擁有下面的配置。
Intel i7 quad-core CPU @ 3.10 GHz
8 GB RAM
NVIDIA GeForce GT 630M display adapter, Full HD (1920 x 1080) resolution
Windows 10 Pro 64-bit OS
所有的Grid控件設置為相同的尺寸和默認的外觀 。
測試應用
我們的基準應用程序允許選擇和運行單獨的測試或者允許一個接一個運行所有的測試。您可以選擇同一個測試運行的次數,這樣可以在結果中得到平均值。
我們這樣做可以減少其他方面的影響,比如操作系統和其他應用程序的交互。所有展示在這里的結果都會運行10次。下面是應用程序窗口。
基準測試應用程序窗口
如果要分析一個指定的用例,運行一個單獨的測試是非常方便的。注意:您需要在不同的測試間比較,在測試運行時請不要改變窗體的尺寸。實際的視圖尺寸會影響性能,就像大屏幕會消耗更多時間和虛擬控件等資源用來布局從而影響其他事件。
這個應用會將測試結果寫進working文件夾下的Excel文件。如果您需要一個更詳細的日志文件,您可以在App.xmal.cs文件中去掉輸出到TraceListener的注釋。
這里最有趣的地方就是,如何去測試異步UI更新時的復雜操作的運行時間。在幾次試驗后,我們發現我們想到的就是最合適的方法,用于去獲取當Girder UI完成更新時的準確時刻。完整源代碼已經附加,您可以去嘗試。我們將很高興收到關于您認為我們可以在某些方面可以提高的反饋。
我們這里不包含任何的控件的二進制版本。如果您想運行應用,您需要下載我們的WPF版本的試用版和其他參與比較的控件的使用版。它們都擁有30天的免費試用期,這將不是問題。
基準
我們選擇ListCollectionView作為數據源并且用下面定義的業務對象來填充它。
public class Customer : INotifyPropertyChanged, IEditableObject
{
public int ID { get; set;}
public string Name { get;}
public string Country { get;}
public int CountryID { get; set;}
public bool Active { get; set;}
public string First { get; set;}
public string Last { get; set;}
public DateTime Hired { get; set;}
public double Weight { get; set;}
public string Father { get;}
public string Brother { get;}
public string Cousin { get;}
}
它提供了12個不同類型的列。
我們嘗試為Grid設置相同的條件,對于某些控件,我們更改了某些設置來達到這一要求。
- 自動生成列
- 固定列寬
- 允許在底部新行位置添加新行
- 隱藏分組和搜素面板
- 可編輯的單元格
每一個基準要遵循下面的步驟
1. 移除上一次測試所創建的所有UI。 調用GC.Collect 和GC.WaitForPendingFinalizers方法,使垃圾回收不會影響下次測試;
2. 初始化下次測試和 Stopwatch計時器;
3. 按照需要的次數執行測試;
4. 測量總時間并計算平均結果;
5. 記錄結果。
下面解釋關于指定基準的實現細節
基準1 創建控件并加載數據。
這個基準創建了一個用戶控件,包含一個用于測試的Grid。 將它插入到可視化樹中并填充數據。 這樣唯一的麻煩就是用代碼創建的Xceed DataGridControl并不能正常工作。因此您將看到附加的應用使用XAML創建它。
基準2: 重新加載數據到存在的控件
基準設置DataGrid的ItemsSource為null,用于清空數據和自動生成的列。然后設置ItemsSource 為一個新的ListCollectionView。在代碼里,它就像下面這樣(對于所有測試的控件都一樣)
public override void Load(IList data)
{
if (data == null)
{
_grid.ItemsSource = null;
}
else
{
_grid.ItemsSource = new ListCollectionView(data);
}
}
基準3: 排列單列
我們嘗試減少測試中自定義的代碼,因此大多數情況下我們通過IcollectionView接口來實現排列。
public override void Sort(bool ascending)
{
ICollectionView dataView = CollectionViewSource.GetDefaultView(_grid.ItemsSource);
dataView.SortDescriptions.Clear();
dataView.SortDescriptions.Add(new SortDescription("ID", ascending ?
ListSortDirection.Ascending : ListSortDirection.Descending)); }
這是非常標準的,并且我們希望每個Grid都應內置支持。但是Syncfusion的 SfDataGrid 并沒有支持,所以我們需要通過SfDataGrid.SortDescriptions屬性來實現排序。
我們測試Infragistics的XamDataGrid時遇到了一個麻煩,他可以使用ICollectionView 排序,但是遇到大數據時變得很慢。當我們想要得到所有控件的對比結果時,我們最終通過FieldLayout.SortedFields來實現它。
基準4和5,滾動100行,滾動整個表單。
我們認為這在測試中可以很好的模擬最終用戶交互,但是沒有找到一個很好的辦法。我們也許可以通過在可視化樹中找到滾動條并滾動。但是相關的代碼也會影響性能,因此我們決定堅持使特定行進入視圖。所有的Grid都擁有ScrollIntoView或者相似的辦法來解決這件事。
測試結果
初始化加載時間
為了在所有的測試中避免計算JIT編譯和XAML解析的次數,我們從每個控件的一個單獨的測試開始整個基準,這跟基準1是幾乎是相同的。 當您在整個應用程序生命周期中第一次運行它,您可以發現它跟接下來的運行不同 。 它被測量作為應用程序的啟動時間,這對WPF很關鍵,下面的測試顯示了不論數據規格幾乎相同的結果。
初始化加載時間
固定寬度基準
下面是1,000,10,000,和100,000項作為數據源的結果
固定列寬下1000 行數據的結果
固定列寬下10,000行數據的結果
固定列寬下100,000行數據的結果
自動列寬基準
在運行了固定列寬的測試之后,我們決定比較一下他們在自動列寬時的表現。我們這項測試只針對四種具有即時自動列寬的Grid。我想在每個Grid的最好情況下得到比較結果,因此我們選擇MS的DataGrid 和Telerik的 RadGridView的默認SizeToHeader選項,C1DataGrid的 默認AutoStar選項和Infragistics的XamDataGrid.的默認FieldLength.InitialAuto選項。
為什么我們不對所有的控件都做這項測試呢?我們的C1FlexGrid和DevExpress的GridControl以及Xceed的DataGridControl不支持即時列寬計算。顯然,這是設計者為了集中于控件的性能而做出的犧牲。上面的所有控件都支持調用方法來自動計算列寬,但您需要在合適的時間來調用合適的方法。這使它很難衡量整體性能,您也不能確定測試結果是完全依賴于性能的。所以在我們的比較中不包含那些控件。
反之,Syncfusion 的SfDataGrid 控件沒有類似MS DataGrid 和其他控件的自動列寬計算的選項,但是由于適用的選項在加載大數據時速度變得很慢,它和其他控件是沒法相比的。所以在這個測試中我們也排出了它。下面是我們分別測試包含1,000, 10,000和100,000條數據的數據源得到的結果。(與固定列寬用的是同樣的基準)
自動寬度下1000行數據的結果。
自動寬度下10,000 行數據的結果。
自動寬度下100,000 行數據的結果。
一些條件
我們的結果與很久之前的關于WPF Grid性能的討論不同,顯然現在的控件都具有可視化能力并且可以處理大量數據,如果您打算為您的應用程序選擇一個Grid,我們的結果是一個很好的參考。
另外沒注意我們沒有測試其他的場景,比如,分組、過濾和列數據可視化。還有,性能并不代表全部,您有可能因為一些其它的原因而喜歡上某個控件。比如易用性,XAML定制能力,內嵌支持的特性數量等。
在制定這些基準的時候,我閱讀了很多關于控件比較的信息,給我很深的印象就是所有的WPFGrid可以分為下面兩類:
- 基于性能的Grid,不包含在自動列寬計算的測試中
- 集中于易用性和XAML運用。
我們的WPF版本中包含以上兩種控件,所以您可以選擇最適應您需要的一種。更多信息,參考附件中關于C1FlexGrid, C1DataGrid 和MS DataGrid詳細功能的比較。
最終,在整個基準的比較的過程中,我情不自禁地要概括我們自己的控件。所以我們又得到一個很有用的信息:2016 v2版本的C1DataGrid控件的速度優于之前的發布版本35%以上。
- 下載WPFGridsBenchmark源代碼 (19 KB zip)
- 下載1000行數據測試結果 (38.5 KB xls)
- 下載10,000行數據測試結果 (38.5 KB xls)
- 下載100,000行數據測試結果(38.5 KB xls)
- 下載C1FlexGrid, C1DataGrid 和MS DataGrid 特性比較表(17.7KB xlsx)
文章列表