WPF官方发布第一个版本至今已经有10年了, 我们几乎在同时也开始了XAML开发。即使经过多年打造,我们依旧尝试提高:我们真的成功打造了高效灵活的控件吗?我没有在其他地方找到任何关于优秀的WPF表格性能比较的介绍,只有少量而年代久远的现在已经不存在的控件的讨论。这个新基准是一种尝试,用来在一些市场相对流行的控件比较中发现我们的优势和不足。

环境

这个基准创建于2016年6月,使用了下面Grid控件。(我们使用的最新试用版)

这个基准运行于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%以上。

WPF平台Grid控件性能比较的更多相关文章

  1. 实现控件WPF(4)----Grid控件实现六方格

    PS:今天上午,非常郁闷,有很多简单基础的问题搞得我有些迷茫,哎,代码几天不写就忘.目前又不当COO,还是得用心记代码哦! 利用Grid控件能很轻松帮助我们实现各种布局.上面就是一个通过Grid单元格 ...

  2. wpf研究之道-grid控件

    想要说些什么,却不知道从哪开始."形而上谓之道,形而下谓之器".与其坐而论道,不如脚踏实地,从最实用的地方开始. 我们先来看看wpf中的grid控件.grid控件是个网格的布局控件 ...

  3. Windows Community Toolkit 3.0 新功能 在WinForms 和 WPF 使用 UWP 控件

    本文告诉大家一个令人震惊的消息,Windows Community Toolkit 有一个大更新,现在的版本是 3.0 .最大的提升就是 WinForm 和 WPF 程序可以使用部分 UWP 控件. ...

  4. WPF中Ribbon控件的使用

    这篇博客将分享如何在WPF程序中使用Ribbon控件.Ribbon可以很大的提高软件的便捷性. 上面截图使Outlook 2010的界面,在Home标签页中,将所属的Menu都平铺的布局,非常容易的可 ...

  5. WPF 在image控件用鼠标拖拽出矩形

    原文:WPF 在image控件用鼠标拖拽出矩形 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 http://lindexi.gitee ...

  6. 示例:WPF中Slider控件封装的缓冲播放进度条控件

    原文:示例:WPF中Slider控件封装的缓冲播放进度条控件 一.目的:模仿播放器播放进度条,支持缓冲任务功能 二.进度: 实现类似播放器中带缓存的播放样式(播放区域.缓冲区域.全部区域等样式) 实现 ...

  7. 扩展ToolBarManager、ListView和Grid控件以实现气球式的ToolTip

    原文:扩展ToolBarManager.ListView和Grid控件以实现气球式的ToolTip infragistics是全球领先的UI工具和用户体验的专家,Infragistics开发了一系列的 ...

  8. 浅尝辄止WPF自定义用户控件(实现颜色调制器)

    主要利用用户控件实现一个自定义的颜色调制控件,实现一个小小的功能,具体实现界面如下. 首先自己新建一个wpf的用户控件类,我就放在我的wpf项目的一个文件夹下面,因为是一个很小的东西,所以就没有用mv ...

  9. 深入探讨WPF的ListView控件

    接上一篇博客初步探讨WPF的ListView控件(涉及模板.查找子控件)  我们继续探讨ListView的用法      一.实现排序功能 需求是这样的:假如我们把学生的分数放入ListView,当我 ...

随机推荐

  1. .NET中异常处理的最佳实践(译)

    本文翻译自CodeProject上的一篇文章,原文地址. 目录 介绍 做最坏的打算 提前检查 不要信任外部数据 可信任的设备:摄像头.鼠标以及键盘 “写操作”同样可能失效 安全编程 不要抛出“new ...

  2. RPC通信框架——RCF介绍

    现有的软件中用了大量的COM接口,导致无法跨平台,当然由于与Windows结合的太紧密,还有很多无法跨平台的地方.那么为了实现跨平台,支持Linux系统,以及后续的分布式,首要任务是去除COM接口. ...

  3. MySQL InnoDB存储引擎

    200 ? "200px" : this.width)!important;} --> 介绍 本篇文章是对Innodb存储引擎的概念进行一个整体的概括,innodb存储引擎的 ...

  4. SQL Server 使用全文索引进行页面搜索

    标签:SQL SERVER/MSSQL SERVER/数据库/DBA/全文索引 概述 全文引擎使用全文索引中的信息来编译可快速搜索表中的特定词或词组的全文查询.全文索引将有关重要的词及其位置的信息存储 ...

  5. enum操作--获取枚举里的最大值

    一个应用系统,如果程序里没有任何enum的使用,我认为它的可读性是有待商榷的. 求枚举里的最大/最小枚举值, 其实是对Array进行操作: enum EnumTest { ddd = , eee } ...

  6. php语言

    <?php//单行注释/*多行注释*///弱类型语言//var a=10;//php定义变量/*$a =10; //变量名前加$$b="hello";var_dump($a) ...

  7. TortoiseSVN Clean up 失败的处理方法

    当使用 TortoiseSVN 下载项目失败之后,重新下载之前需要 Clean up,在 TortoiseSVN 中 Clean up 总是失败.   在命令行行中执行 svn cleanup 就成功 ...

  8. Sql Server系列:Transact-SQL概述

    结构化查询语言(Structure Query Language,SQL)是对数据库进行查询和修改的语言.Transact-SQL是SQL的一种实现形式,它包含了标准的SQL语言部分. 根据完成的具体 ...

  9. Sql Server系列:数据类型转换函数

    T-SQL提供了两个显示转换的函数:CAST函数和CONVERT函数. 1. CAST函数 语法: CAST ( expression AS data_type [ ( length ) ] ) 示例 ...

  10. 【原创】开源.NET排列组合组件KwCombinatorics使用(三)——笛卡尔积组合

           本博客所有文章分类的总目录:本博客博文总目录-实时更新 本博客其他.NET开源项目文章目录:[目录]本博客其他.NET开源项目文章目录 KwCombinatorics组件文章目录: 1. ...