C# .NET合并两个对象列表的两种方式性能差异咨询
两种List合并方式的性能对比与选择建议
作为一个常年和C#集合打交道的开发者,我来给你掰扯掰扯这两种合并List的方式到底差在哪,以及要不要替换~
先说说底层实现的差异
方式1:AddRange批量添加
.NET里List<T>.AddRange(IEnumerable<T>)的底层逻辑是很聪明的:
- 它会先尝试获取传入集合的长度(比如如果是List的话直接拿
Count),计算出需要的总容量 - 如果当前合并后的List容量不够,会一次性扩容到足够的大小,避免多次扩容的开销
- 然后直接把元素批量复制到内部的数组里,整个过程是O(n)的连续内存操作,效率很高
对应的代码示例:
var mergedList = new List<Person>(); mergedList.AddRange(list1); mergedList.AddRange(list2);
方式2:foreach + Add逐个添加
这种方式的核心问题在于每次调用Add时的容量检查:
- 每次
Add都会判断当前List的剩余容量,如果不够就触发扩容(默认是把容量翻倍,然后把现有元素全量复制到新数组) - 如果你的list1、list2规模较大,这个扩容操作会触发好多次,每次数组复制都是额外的性能损耗
- 而且逐个添加是零散的内存写入操作,效率远不如批量复制
对应的代码示例:
var mergedList = new List<Person>(); foreach(var item in list1) { mergedList.Add(item); } foreach(var item in list2) { mergedList.Add(item); }
性能差异到底有多大?
- 如果是小列表(比如每个列表只有几个、几十个元素):两种方式的性能差异几乎可以忽略,肉眼完全感知不到
- 如果是大列表(比如每个列表有几千、几万个元素):
AddRange的优势会非常明显,可能快好几倍甚至一个数量级——毕竟少了N次扩容和数组复制的开销
要不要把方式2替换成方式1?
给你两个判断标准:
- 如果你的合并操作是高频执行,或者处理的是较大规模的列表:强烈建议换成方式1,既提升性能,代码也更简洁
- 如果只是偶尔合并几个小列表:完全没必要折腾,两种方式都能用,甚至方式2的可读性对新手来说还更直观一点
额外提一句:如果是合并多个列表,方式1的代码会更干净——比如合并3个列表只要连续写三次AddRange,而方式2要写三个foreach,代码冗余度会很高。
内容的提问来源于stack exchange,提问作者Koni
相关产品推荐
相关产品推荐

