WPF平台Grid控件性能比较
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)
WPF平台Grid控件性能比较的更多相关文章
- 实现控件WPF(4)----Grid控件实现六方格
PS:今天上午,非常郁闷,有很多简单基础的问题搞得我有些迷茫,哎,代码几天不写就忘.目前又不当COO,还是得用心记代码哦! 利用Grid控件能很轻松帮助我们实现各种布局.上面就是一个通过Grid单元格 ...
- wpf研究之道-grid控件
想要说些什么,却不知道从哪开始."形而上谓之道,形而下谓之器".与其坐而论道,不如脚踏实地,从最实用的地方开始. 我们先来看看wpf中的grid控件.grid控件是个网格的布局控件 ...
- Windows Community Toolkit 3.0 新功能 在WinForms 和 WPF 使用 UWP 控件
本文告诉大家一个令人震惊的消息,Windows Community Toolkit 有一个大更新,现在的版本是 3.0 .最大的提升就是 WinForm 和 WPF 程序可以使用部分 UWP 控件. ...
- WPF中Ribbon控件的使用
这篇博客将分享如何在WPF程序中使用Ribbon控件.Ribbon可以很大的提高软件的便捷性. 上面截图使Outlook 2010的界面,在Home标签页中,将所属的Menu都平铺的布局,非常容易的可 ...
- WPF 在image控件用鼠标拖拽出矩形
原文:WPF 在image控件用鼠标拖拽出矩形 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 http://lindexi.gitee ...
- 示例:WPF中Slider控件封装的缓冲播放进度条控件
原文:示例:WPF中Slider控件封装的缓冲播放进度条控件 一.目的:模仿播放器播放进度条,支持缓冲任务功能 二.进度: 实现类似播放器中带缓存的播放样式(播放区域.缓冲区域.全部区域等样式) 实现 ...
- 扩展ToolBarManager、ListView和Grid控件以实现气球式的ToolTip
原文:扩展ToolBarManager.ListView和Grid控件以实现气球式的ToolTip infragistics是全球领先的UI工具和用户体验的专家,Infragistics开发了一系列的 ...
- 浅尝辄止WPF自定义用户控件(实现颜色调制器)
主要利用用户控件实现一个自定义的颜色调制控件,实现一个小小的功能,具体实现界面如下. 首先自己新建一个wpf的用户控件类,我就放在我的wpf项目的一个文件夹下面,因为是一个很小的东西,所以就没有用mv ...
- 深入探讨WPF的ListView控件
接上一篇博客初步探讨WPF的ListView控件(涉及模板.查找子控件) 我们继续探讨ListView的用法 一.实现排序功能 需求是这样的:假如我们把学生的分数放入ListView,当我 ...
随机推荐
- 前端er是否忽略了某些东西?——读《ppk谈JavaScript》
关于书 “不知道ppk的网站QuirksMode,说明你可能还没有真正成为资深的JavaScript程序员.” ——Roger Johansson,瑞典资深Web专家. ppk是世界级前端技术专家,W ...
- 比官方教程代码更简短的SignalR Server Broadcast示例
SignalR是微软ASP.NET技术体系中的新成员. 在www.asp.net网站上的SignalR专区有一篇SignalR的入门级教程<Tutorial: Server Broadcast ...
- JavaScript学习笔记之string
字符串定义: 1,var myString=“内容”:or var myString=‘内容’ 2,var myString= new String(“内容”) ---〉创建对象, ...
- 记一个简单的保护if 的sh脚本
真是坑爹,就下面的sh,竟然也写了很久! if [ `pwd` != '/usr/xx/bin/tomcat' ] then echo "rstall is not allowed in c ...
- 关闭form上chrome的autofill
Chrome的autofill会自动找到form中的type=password的元素,然后把这个元素前面的元素当做是用户名,它不在乎这个元素叫什么名字.这样又是注册又是登录,你会发现它自作聪明的aut ...
- selenium结合最新版的sikuli使用
sikuli安装,下载sikulixsetup-1.1.0.jar,地址:https://launchpad.net/sikuli/sikulix/1.1.0 在装有Java环境的机器上直接双击jar ...
- python中协程
在引出协成概念之前先说说python的进程和线程. 进程: 进程是正在执行程序实例.执行程序的过程中,内核会讲程序代码载入虚拟内存,为程序变量分配空间,建立 bookkeeping 数据结构,来记录与 ...
- 上传伪技术~很多人都以为判断了后缀,判断了ContentType,判断了头文件就真的安全了。是吗?
今天群里有人聊图片上传,简单说下自己的经验(大牛勿喷) 0.如果你的方法里面是有指定路径的,记得一定要过滤../,比如你把 aa文件夹设置了权限,一些类似于exe,asp,php之类的文件不能执行,那 ...
- 【Win 10 应用开发】Toast通知激活应用——前台&后台
老周最近热衷于讲故事,接下来还是讲故事时间. 有人问我:你上大学的时候,有加入过学生会吗?读大学有没有必要加入学生会? 哎哟,这怎么回答呢,从短期来说,加入学生会有点用,至少可以娱乐一下,运气好的话, ...
- Android之JSON解析
做个Android网络编程的同学一定对于JSON解析一点都不陌生,因为现在我们通过手机向服务器请求资源,服务器给我们返回的数据资源一般都是以JSON格式返回,当然还有一些通过XML格式返回,相对JSO ...