HashSet性能(与ObservableCollection相比)
本文关键字:相比 ObservableCollection 性能 HashSet | 更新日期: 2023-09-27 18:34:34
我目前正在做一个项目,我必须管理大量独特的元素。每个元素都有 ~20 个属性,每个元素都有一个公共属性 DateTime。
DateTime 属性不是唯一的,因此我无法使用通用字典来存储我的数据。
目前,我将这些元素放入 ObservableCollection 中,但是从集合中删除元素的性能非常慢,我最终等待 ~20 秒才能从 ~25.000 个元素的集合中删除 ~7000 个元素。
(搜索操作似乎非常有效,从 300.000 个元素的未排序集合中查找 80 个随机选择的元素只需 ~30 毫秒(。
每个元素通过简单地返回 DateTime.GetHashCode(( 来实现 GetHashCode(( 方法。
我认为使用 HashSet 而不是 ObservableCollection 会大大提高我的性能,但它似乎根本没有效果......
使用通用词典更糟糕...
如果元素具有"良好"的哈希函数(很少有元素具有相同的哈希代码(,那么 HashSet 不是比 ObservableCollection 更强大吗?
您必须重写对象的 Equals 方法。
因为 HashSet 使用内部 IEqualityComparer 实例,该实例通常首先检查 (null(,然后使用重写的 Equals 方法将"非空"项与另一个项进行比较:
class MyObject
{
public Guid Id { get; set; }
public override bool Equals(object other)
{
if (other is MyObject)
{
// use the 'Id' property as identifier
MyObject myObj = (MyObject)obj;
return myObj.Id == this.Id;
}
// is not a 'MyObject' based object
return base.Equals(other);
}
}
您还可以使用字符串或与您的对象相当的任何其他类型的对象。
编辑:
因此,您可以使用HashSet而不是OberservableCollection。最后一个集合类型通常较慢,因为在每次集合更改(添加、删除、清除、插入等(时,都会触发 PropertyChanged 和 CollectionChanged 事件。
减少更改通知来优化ObservableCollection
的性能。我编写了一个自定义集合类,ItemCollection
,具有更新机制(BeginUpdate
/EndUpdate
(:
ItemCollection<Customer> customers = new ItemCollection<Customer>
customers.BeginUpdate();
customers.Add( new Customer( "Joe", "Smith" ) );
customers.Add( new Customer( "Mary", "Jones" ) );
customers.Add( new Customer( "Lisa", "Black" ) );
customers.Add( new Customer( "Peter", "Brown" ) );
customers.EndUpdate();
包含源代码的文章:基于 XAML 的应用程序的表示模式。
好吧,马塞尔的回答是正确的,但如果性能真的很重要,你可以稍微改进他的平等方法:
class MyObject
{
public Guid Id { get; set; }
public override bool Equals(object other)
{
MyObject myObj = obj as MyObject;
if (myObj != null)
{
// use the 'Id' property as identifier
return myObj.Id == this.Id;
}
// is not a 'MyObject' based object
return base.Equals(other);
}
}
使用此方法,您可以避免两次检查对象是否属于特定类型的昂贵函数,只需调用一次并执行快速 null 检查。有关它的更多信息,您可以查看 Eric 的这篇文章。