为啥使用 CollectionViewSource.SortDescriptions 排序很慢?
Posted
技术标签:
【中文标题】为啥使用 CollectionViewSource.SortDescriptions 排序很慢?【英文标题】:Why sorting using CollectionViewSource.SortDescriptions is slow?为什么使用 CollectionViewSource.SortDescriptions 排序很慢? 【发布时间】:2010-12-10 15:52:45 【问题描述】:这是单击DataGrid
中的列标题时的默认排序方法。当底层列表包含 100,000 个项目时,刷新视图大约需要 20 秒。在CollectionView
上设置SortDescription
s 时可以观察到相同的延迟。
使用ListCollectionView.CustomSort
或通过对列表进行排序和重新分配几乎可以立即进行排序。
为什么会出现这种延迟?这只是对绑定属性的“反射税”吗?
【问题讨论】:
【参考方案1】:过滤的最佳性能调整是切换 DataGridRow Visibility。它产生了巨大的差异!
1.将 IsVisible 属性添加到您将 DataGrid 的 ItemSource 绑定到的 Collection Item。
private bool _isVisible = true;
public bool IsVisible
get return _isVisible;
set
if (_isVisible == value)
return;
_isVisible = value;
RaisePropertyChanged(()=>IsVisible);
2.通过将 DataGridRow 绑定到您的 IsVisible 属性来触发其可见性:
<DataGrid.ItemContainerStyle>
<Style TargetType="x:Type DataGridRow">
<Setter Property="Visibility"
Value="Binding Path=IsVisible,
Converter=StaticResource BoolToVisibility"/>
</Style>
</DataGrid.ItemContainerStyle>
3.好吧,我猜你也必须在某个地方设置 IsVisible,比如在你的 ViewModel 中。这只是我正在做的一个示例(只是复制/粘贴工作) - 基本上根据我的其他 ViewModel 中的某些标准将 IsVisible 设置为 true 或 false:
FilterViewModel.OnFilter += (s, a) =>
foreach (Row row in ViewModel.Rows)
row.IsVisible = !FilterViewModel.FilteringItems.Any(item =>
item.IsSelected && item.Name == row.Name);
;
【讨论】:
这对我有用。顺便说一句,这就是在 Angular 中解决类似问题的方法:)。【参考方案2】:你是对的,这是一种反射税。前段时间我非常仔细地研究了 DataGrid 的性能,而反射在这里是一个瓶颈。无论排序算法有多快,它们都不会在两次比较之间缓存属性值。因此,即使您有 n*ln(n) 比较,在 n == 100 000 的情况下,您也会得到 ~1 000 000 次操作。每个操作数都使用反射来获取价值,因此您有 2 000 000 次调用反射税 :) ...ListCollectionView.CustomSort
是这里的理想解决方案。
PS:最后,我们写了基于 ListView 的网格,因为我们对 DataGrid 的渲染性能也不满意……但那是另一回事了 :)
【讨论】:
这适用于实时排序吗? (ListCollectionView.LiveSortingProperties)以上是关于为啥使用 CollectionViewSource.SortDescriptions 排序很慢?的主要内容,如果未能解决你的问题,请参考以下文章
CollectionViewSource+PropertyGroupDescription - 组中的项目数
如何使用带有 CollectionViewSource 的增量加载集合对 UWP 中的列表视图项进行分组?
检查 CollectionViewSource 中的行是不是是新行