我在一个类中发现了一些非常讨厌的代码(让我们称之为 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实现最快的实现?
感谢。
答案 0 :(得分:5)
LinkedList<T>
基本上使用explicit interface implementation实现ICollection<T>
。因此Add
方法仅在您将其视为“ICollection<T>
”时才可用。
重点是,如果您知道自己正在使用链接列表,则应使用AddFirst
或AddLast
代替。
答案 1 :(得分:1)
没有一个单独的类在添加和删除方面最快。它们都是在某些情况下更快速地构建的,并且它们都有它们的缺点。在大多数情况下,List
可以快速添加到最后,但它会定期进行昂贵的添加,包括复制每个元素。当您开始在接近开始时添加项目时,它会变得越来越昂贵。最后拆卸很便宜,而且随着你的开始越来越昂贵。
LinkedList
可以有效地添加到开头或结尾,但是这些添加仍然比添加到List
的结尾慢得多(但没有任何大的添加)。添加到LinkedList
的开头或结尾以外的位置会变得很快。在大多数实际情况中,LinkedList
从表现的角度来看并不是一个好的选择。
我可以继续,但这将是一段时间。关键在于我们需要了解有关如何使用集合的更多细节,以便建议更高效的替代方案(或使用现有集合的不同方式)。
由于您已经描述了您拥有的只是一组不需要订购的数据,只需要有效地添加/删除/迭代所有最佳集合将是HashSet<T>
。你可以自己研究一个基于散列的数据结构的内部工作方式(它相当酷),但关键是它是一个无序数据结构,非常有效地添加/删除元素,并且你可以有效地迭代。这是您的理想选择。基于哈希的数据结构要记住的一件事是,您的对象需要具有有意义的GetHashCode
和Equals
的实现(默认值通常不适用于您的自定义类型)。如果您使用int
或string
之类的密钥作为密钥,那么它已经有了很好的实现。