为啥使用 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 上设置SortDescriptions 时可以观察到相同的延迟。

使用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 上触发过滤器

CollectionViewSource+PropertyGroupDescription - 组中的项目数

如何使用带有 CollectionViewSource 的增量加载集合对 UWP 中的列表视图项进行分组?

检查 CollectionViewSource 中的行是不是是新行

CollectionViewSource,如何过​​滤数据?

[Wpf]在C#中添加 collectionViewSource