在c#中,数组列表和List<>有什么区别?

是不是只有List<>有类型而ArrayList没有?


当前回答

再加上以上几点。在64位操作系统中使用ArrayList占用的内存是32位操作系统的2倍。同时,泛型列表list <T>占用的内存比ArrayList少得多。

例如,如果我们在32位中使用一个19MB的数组列表,那么在64位中它将占用39MB。但是如果你有一个32位的8MB的通用列表list <int>,它在64位只需要8.1MB,这与ArrayList相比相差了481%。

来源:数组列表与通用列表的基本类型和64位

其他回答

要添加的另一个区别是线程同步。

ArrayList provides some thread-safety through the Synchronized property, which returns a thread-safe wrapper around the collection. The wrapper works by locking the entire collection on every add or remove operation. Therefore, each thread that is attempting to access the collection must wait for its turn to take the one lock. This is not scalable and can cause significant performance degradation for large collections. List<T> does not provide any thread synchronization; user code must provide all synchronization when items are added or removed on multiple threads concurrently.

更多信息在这里线程同步在.Net框架

性能已经在几个答案中被提到作为一个区分因素,但是要解决“数组列表有多慢?”和“为什么整体上更慢?”,请看下面的内容。

当使用值类型作为元素时,ArrayList的性能会急剧下降。考虑简单地添加元素的情况。由于装箱正在进行——因为ArrayList的Add只接受对象参数——垃圾收集器被触发执行比List<T>更多的工作。

时差是多少?至少比List<T>慢几倍。看看在数组列表中添加10mil int值和List<T>的代码会发生什么:

在“均值”列(黄色突出显示)中,这是5倍的运行时间差异。还要注意为每个gc执行的垃圾收集数量的差异,用红色突出显示(每1000次运行没有gc)。

使用分析器快速查看发生了什么,这表明大部分时间都花在了gc上,而不是实际添加元素。下面的棕色条表示阻塞垃圾收集器活动:

我在这里https://mihai-albert.com/2019/12/15/boxing-performance-in-c-analysis-and-benchmark/写了一篇关于上述ArrayList场景的详细分析。

Jeffrey Richter的《CLR via c#》中也有类似的发现。第12章(泛型):

[…] When I compile and run a release build (with optimizations turned on) of this program on my computer, I get the following output. 00:00:01.6246959 (GCs= 6) List<Int32> 00:00:10.8555008 (GCs=390) ArrayList of Int32 00:00:02.5427847 (GCs= 4) List<String> 00:00:02.7944831 (GCs= 7) ArrayList of String The output here shows that using the generic List algorithm with the Int32 type is much faster than using the non-generic ArrayList algorithm with Int32. In fact, the difference is phenomenal: 1.6 seconds versus almost 11 seconds. That’s ~7 times faster! In addition, using a value type (Int32) with ArrayList causes a lot of boxing operations to occur, which results in 390 garbage collections. Meanwhile, the List algorithm required 6 garbage collections.

是的,差不多。List<T>是泛型类。它支持存储特定类型的值,而不强制转换为对象(当T是ArrayList情况下的值类型时,这会引起装箱/拆箱开销)。ArrayList仅存储对象引用。作为一个泛型集合,List<T>实现了泛型IEnumerable<T>接口,可以很容易地在LINQ中使用(不需要任何Cast或OfType调用)。

ArrayList属于c#没有泛型的时代。不赞成使用List<T>。你不应该在以。net >= 2.0为目标的新代码中使用ArrayList,除非你必须与使用它的旧API进行交互。

ArrayList不是类型安全的,而List<T>是类型安全的。简单:)。

ArrayList是不同类型数据的集合,而List<>是其自身依赖的相似类型数据的集合。