在添加/删除元素方面最快实现IList <t> / ICollection <t> </t> </t>

时间:2012-08-09 18:44:13

标签: c# .net c#-4.0 collections

我在一个类中发现了一些非常讨厌的代码(让我们称之为 MyClass ),它广泛使用 T.Add / Remove 方法列表。同一个类也将该集合公开为IList为T类型的属性,因此更改类型将涉及一些重构。

此外,MyClass集合用作事件侦听器对象的容器,因此客户端代码只是订阅(将自身添加到集合中)和取消订阅(从集合中删除)。订单无关紧要,无论是列表的开始/中间/结尾。

为了提高性能,我想替换内部实现细节,用...替换List of T。我不知道是什么。我尝试了T的LinkedList,但它没有实现T的IList。我查看了IList of T at MSDN,但是没有实现IList的类列表,所以我可以比较文档。

另一件事是我尝试将T的IList更改为IC的ICollection,这可能是一个解决方案(因为 MyClass 的客户端代码使用添加/删除方法,因此不需要重构)但有趣的事情发生了:

        LinkedList<string> list = new LinkedList<string>();
        list.Add("test");

由于出现错误,此代码无法编译:

  

'System.Collections.Generic.LinkedList'不包含   “添加”的定义,没有扩展方法“添加”

但是当我把它改为:

        ICollection<string> list = new LinkedList<string>();
        list.Add("test");
然后我工作了。你能解释一下为什么第一个样本没有编译+在.NET Framework中添加/删除项目中哪个是IL的T实现最快的实现?

感谢。

2 个答案:

答案 0 :(得分:5)

LinkedList<T>基本上使用explicit interface implementation实现ICollection<T>。因此Add方法仅在您将其视为“ICollection<T>”时才可用。

重点是,如果您知道自己正在使用链接列表,则应使用AddFirstAddLast代替。

答案 1 :(得分:1)

没有一个单独的类在添加和删除方面最快。它们都是在某些情况下更快速地构建的,并且它们都有它们的缺点。在大多数情况下,List可以快速添加到最后,但它会定期进行昂贵的添加,包括复制每个元素。当您开始在接近开始时添加项目时,它会变得越来越昂贵。最后拆卸很便宜,而且随着你的开始越来越昂贵。

LinkedList可以有效地添加到开头或结尾,但是这些添加仍然比添加到List的结尾慢得多(但没有任何大的添加)。添加到LinkedList的开头或结尾以外的位置会变得很快。在大多数实际情况中,LinkedList从表现的角度来看并不是一个好的选择。

我可以继续,但这将是一段时间。关键在于我们需要了解有关如何使用集合的更多细节,以便建议更高效的替代方案(或使用现有集合的不同方式)。

由于您已经描述了您拥有的只是一组不需要订购的数据,只需要有效地添加/删除/迭代所有最佳集合将是HashSet<T>。你可以自己研究一个基于散列的数据结构的内部工作方式(它相当酷),但关键是它是一个无序数据结构,非常有效地添加/删除元素,并且你可以有效地迭代。这是您的理想选择。基于哈希的数据结构要记住的一件事是,您的对象需要具有有意义的GetHashCodeEquals的实现(默认值通常不适用于您的自定义类型)。如果您使用intstring之类的密钥作为密钥,那么它已经有了很好的实现。