Meh*_*ari 508
是的,差不多.List<T>
是一个通用类.它支持存储特定类型的值而无需进行转换或从中获取object
(当T
在该ArrayList
情况下为值类型时,会产生装箱/拆箱开销).ArrayList
只是存储object
参考.作为通用集合,List<T>
实现通用IEnumerable<T>
接口,可以在LINQ中轻松使用(无需任何Cast
或OfType
调用).
ArrayList
属于C#没有泛型的日子.它被弃用了List<T>
.ArrayList
除非必须与使用它的旧API接口,否则不应使用面向.NET> = 2.0的新代码.
小智 97
使用List<T>
您可以防止出现错误.避免运行时转换错误非常有用.
例:
在这里(使用ArrayList
)您可以编译此代码,但稍后您将看到执行错误.
ArrayList array1 = new ArrayList();
array1.Add(1);
array1.Add("Pony"); //No error at compile process
int total = 0;
foreach (int num in array1)
{
total += num; //-->Runtime Error
}
Run Code Online (Sandbox Code Playgroud)
如果使用List
,则可以避免这些错误:
List<int> list1 = new List<int>();
list1.Add(1);
//list1.Add("Pony"); //<-- Error at compile process
int total = 0;
foreach (int num in list1 )
{
total += num;
}
Run Code Online (Sandbox Code Playgroud)
参考: MSDN
Ano*_*oop 23
添加到上述几点.使用ArrayList
在64位操作系统将占用2个内存比使用32位操作系统.同时,通用列表List<T>
将使用比内存低很多的内存ArrayList
.
例如,如果我们ArrayList
在32位中使用19MB,那么在64位中需要39MB.但是如果你有一个List<int>
32位的8MB 通用列表,那么64位只需要8.1MB,与ArrayList相比,这是一个惊人的481%的差异.
Source:ArrayList与原始类型和64位的泛型List
Nul*_*nce 18
要添加的另一个区别是线程同步.
ArrayList
通过Synchronized属性提供一些线程安全性,该属性返回集合周围的线程安全包装器.包装器通过在每次添加或删除操作时锁定整个集合来工作.因此,尝试访问集合的每个线程必须等待轮到一个锁.这不可扩展,可能会导致大型集合的性能显着下降.
List<T>
不提供任何线程同步; 用户代码必须在多个线程上同时添加或删除项目时提供所有同步.
简单的答案是,
ArrayList arrayList = new ArrayList();
List<int> list = new List<int>();
arrayList.Add(1);
arrayList.Add("String");
arrayList.Add(new object());
list.Add(1);
list.Add("String"); // Compile-time Error
list.Add(new object()); // Compile-time Error
Run Code Online (Sandbox Code Playgroud)
请阅读Microsoft官方文档:https : //blogs.msdn.microsoft.com/kcwalina/2005/09/23/system-collections-vs-system-collection-generic-and-system-collections-objectmodel/
注意:在了解差异之前,您应该先了解泛型:https : //docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/generics/
在几个答案中已经提到性能是一个区别因素,但是要解决 \xe2\x80\x9c慢了多少ArrayList
?\xe2\x80\x9d 和 \xe2\x80\x9c为什么整体速度较慢?\xe2\x80\x9d,看看下面。
每当值类型用作元素时,性能都会急剧下降ArrayList
。考虑简单添加元素的情况。由于装箱正在进行 - 因为ArrayList
\xe2\x80\x99s Add 仅接受object
参数 - 垃圾收集器被触发执行比List<T>
.
时差是多少?至少比 with 慢几倍List<T>
。只需看一下将 1000 万个 int 值添加到ArrayList
vs 的代码会发生什么List<T>
:\n\n
\xe2\x80\x99在 \xe2\x80\x98Mean\xe2\x80\x99 列中运行时间差异为5 倍,以黄色突出显示。另请注意每个垃圾收集次数的差异,以红色突出显示(GC 数量/1000 次运行)。
\n\n使用分析器快速查看\xe2\x80\x99 发生的情况,表明大部分时间都花在了 GC 上,而不是实际添加元素。下面的棕色条代表阻塞的垃圾收集器活动:\n
我\xe2\x80\x99在这里对上述ArrayList
场景进行了详细分析https://mihai-albert.com/2019/12/15/boxing-performance-in-c-analysis-and-benchmark/。
Jeffrey Richter 通过 C#\xe2\x80\x9d 在 \xe2\x80\x9cCLR 中发现了类似的结果。来自第 12 章(泛型):
\n\n\n\n[\xe2\x80\xa6] 当我在计算机上编译并运行该程序的发布版本(打开优化)时,我得到以下输出。
\n\n00:00:01.6246959 (GCs= 6) List<Int32>
\n\n
\n 00:00:10.8555008 (GCs=390) Int32 ArrayList
\n 00:00:02.5427847 (GCs= 4) List<String>
\n 00:00 :02.7944831 (GCs= 7) 字符串数组列表此处的输出显示\n 使用 Int32 类型的泛型 List 算法比使用 Int32 类型的非泛型 ArrayList 算法要快得多。事实上,差异是惊人的:1.6 秒对比几乎 11 秒。那 \xe2\x80\x99s 快了约 7 倍!此外,将值类型 (Int32) 与 ArrayList 一起使用会导致发生大量装箱操作,从而导致 390 次垃圾回收。同时,List\n 算法需要 6 次垃圾回收。
\n
归档时间: |
|
查看次数: |
352141 次 |
最近记录: |