List 和 Collection 性能比较

时间:2022-10-27 21:27:50

List<T> 继承了接口:IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable

Collection<T>继承了接口:IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable

通过接口比较发现两者继承了相同的接口。以下是MSDN对两者的描述。

 

---------------------------------------MSDN 对List<T>的描述------------------------------------------------------------------------------------

List<(Of <(T>)>) 类是 ArrayList 类的泛型等效类。该类使用大小可按需动态增加的数组实现 IList<(Of <(T>)>) 泛型接口。

List<(Of <(T>)>) 类既使用相等比较器又使用排序比较器。

  • 诸如 Contains、IndexOf、LastIndexOf 和 Remove 这样的方法对列表元素使用相等比较器。类型 T 的默认相等比较器按如下方式确定。如果类型 T 实现 IEquatable<(Of <(T>)>) 泛型接口,则相等比较器为该接口的 Equals(T) 方法;否则,默认相等比较器为 Object..::.Equals(Object)。

  • 诸如 BinarySearch 和 Sort 这样的方法对列表元素使用排序比较器。类型 T 的默认比较器按如下方式确定。 如果类型 T 实现 IComparable<(Of <(T>)>) 泛型接口,则默认比较器为该接口的 CompareTo(T) 方法;否则,如果类型 T 实现非泛型 IComparable 接口,则默认比较器为该接口的 CompareTo(Object) 方法。如果类型 T 没有实现其中任一个接口,则不存在默认比较器,并且必须显式提供比较器或比较委托。

List<(Of <(T>)>) 不保证是排序的。 在执行要求 List<(Of <(T>)>) 已排序的操作(例如 BinarySearch)之前,您必须对 List<(Of <(T>)>) 进行排序。可使用一个整数索引访问此集合中的元素。此集合中的索引从零开始。List<(Of <(T>)>) 接受 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing) 作为引用类型的有效值并且允许有重复的元素。

性能注意事项

在决定使用 List<(Of <(T>)>) 还是使用 ArrayList 类(两者具有类似的功能)时,记住 List<(Of <(T>)>) 类在大多数情况下执行得更好并且是类型安全的。如果对 List<(Of <(T>)>) 类的类型 T 使用引用类型,则两个类的行为是完全相同的。但是,如果对类型 T 使用值类型,则需要考虑实现和装箱问题。

如果对类型 T 使用值类型,则编译器将特别针对该值类型生成 List<(Of <(T>)>) 类的实现。这意味着不必对 List<(Of <(T>)>) 对象的列表元素进行装箱就可以使用该元素,并且在创建大约 500 个列表元素之后,不对列表元素装箱所节省的内存将大于生成该类实现所使用的内存。

确保用于类型 T 的值类型实现 IEquatable<(Of <(T>)>) 泛型接口。如果未实现,则诸如 Contains 这样的方法必须调用 Object..::.Equals(Object) 方法,后者对受影响的列表元素进行装箱。如果值类型实现 IComparable 接口,并且您拥有源代码,则还应实现 IComparable<(Of <(T>)>) 泛型接口以防止 BinarySearch 和 Sort 方法对列表元素进行装箱。如果您不拥有源代码,则将一个 IComparer<(Of <(T>)>) 对象传递给 BinarySearch 和 Sort 方法。

使用 List<(Of <(T>)>) 类的特定于类型的实现,而不是使用 ArrayList 类或自己编写强类型包装集合,这样是很有好处的。原因是您的实现必须做 .NET Framework 已经为您完成的工作,并且公共语言运行库能够共享 Microsoft 中间语言代码和元素据,这是您的实现所无法做到的。

 

-----------------------------------------------------MSDN 对Collection<T>的描述----------------------------------------------------------------------------------

通过创建 Collection<(Of <(T>)>) 类的一个构造类型的实例,可以立即使用该类;您只需指定要包含在集合中的对象类型即可。此外,您可以从任意构造类型派生自己的集合类型,或者从 Collection<(Of <(T>)>) 类本身派生出泛型集合类型。

Collection<(Of <(T>)>) 类提供了受保护的方法,这些方法可用于在添加和移除项、清除集合或设置现有项的值时自定义该类的行为。

大多数 Collection<(Of <(T>)>) 对象都可以被修改。但是,不能修改使用只读 IList<(Of <(T>)>) 对象初始化的 Collection<(Of <(T>)>) 对象。有关此类的只读版本,请参见 ReadOnlyCollection<(Of <(T>)>)。可使用一个整数索引访问此集合中的元素。 此集合中的索引从零开始。Collection<(Of <(T>)>) 接受 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing) 作为引用类型的有效值并且允许有重复的元素。

给实现者的说明:

提供此基类旨在使实施者更易于创建自定义集合。实现者最好扩展此基类,而不是创建自己的类。

 

 

 1  class  Program
 2      {
 3           static   void  Main( string [] args)
 4          {
 5              Stopwatch sw  =   new  Stopwatch();
 6              sw.Start();
 7              ArrayList arrayListObjects  =   new  ArrayList();
 8 
 9               for  ( int  i  =   0 ; i  <   100000 ; i ++ )
10              {
11                  arrayListObjects.Add( new  Member { PropertyOne  =   new  Random().Next( 1000 10000 ), PropertyTwo  =   new  Random().Next( 1000 10000 ) });
12              }
13              sw.Stop();
14              Console.WriteLine( " ArrayList Performance:  " + sw.ElapsedMilliseconds.ToString());
15 
16              sw.Reset();
17              sw.Start();
18              List < object >  listObjects  =   new  List < object > ();
19               for  ( int  i  =   0 ; i  <   100000 ; i ++ )
20              {
21                  listObjects.Add( new  Member { PropertyOne  =   new  Random().Next( 1000 10000 ),PropertyTwo  =   new  Random().Next( 1000 10000 )});
22              }
23              sw.Stop();
24              Console.WriteLine( " List<T> Performance:  " + sw.ElapsedMilliseconds.ToString());
25 
26              sw.Reset();
27              sw.Start();
28 
29              Collection < object >  collectionObjects  =   new  Collection < object > ();
30 
31               for  ( int  i  =   0 ; i  <   100000 ; i ++ )
32              {
33                  collectionObjects.Add( new  Member { PropertyOne  =   new  Random().Next( 1000 10000 ), PropertyTwo  =   new  Random().Next( 1000 10000 ) });
34              }
35 
36              sw.Stop();
37 
38              Console.WriteLine( " Collection<T> Performance:  " + sw.ElapsedMilliseconds.ToString());
39 
40              Console.Read();
41          }
42      }
43 
44       public   class  Member
45      {
46           public   int  PropertyOne {  get set ; }
47           public   int  PropertyTwo {  get set ; }
48      }

 

 

List 和 Collection 性能比较

 

通过测试添加100000个对象发现,三者的性能是非常的接近的!