C#:数组与列表的差异

C# 数组(Array)是‌固定长度‌的连续内存块,适合‌已知规模、高频只读 ‌场景;泛型列表(List<T>)是‌动态扩容 ‌的封装结构,适合‌规模不确定、需频繁增删‌场景。两者索引访问均为 O(1),但底层开销与内存行为差异显著。

关键差异对比

表格

维度 数组 (T[]) 列表 (List<T>)
长度可变性 ❌ 创建后不可变(需 Array.Resize 重建) ✅ 自动扩容(默认策略:容量不足时翻倍)
内存布局 纯连续内存,无额外字段,GC 压力小 内部含数组 + Count/Capacity 字段;未设容量时易产生冗余空间
访问性能 极快(IL 指令 ldelem 直接寻址,缓存友好) 略慢(含方法调用、边界检查;Debug 模式更明显)
增删操作 不支持原生增删;中间插入/删除需手动移动元素(O(n)) Add() 均摊 O(1)(尾部);Insert/RemoveAt 为 O(n)(需移位)
功能丰富度 基础操作(索引、LengthArray.Sort 等) 丰富方法(Add/Remove/Find/Contains/LINQ 兼容等)
类型安全 泛型原生支持,值类型零装箱 泛型实现,值类型零装箱(优于非泛型 ArrayList
典型场景 图像像素缓冲、配置常量表、高频遍历固定数据集 用户输入收集、运行时对象列表、迭代开发中数据量不确定场景

性能与优化要点

  • 内存占用 ‌:未预设容量的 List<T> 因多次扩容,峰值内存可达同规模数组的‌5~10 倍 ‌;建议用 new List<T>(expectedSize) 预分配。
  • GC 影响 ‌:短生命周期大 List 易触发 Gen0 GC;局部小数组常被 JIT 优化至栈上(配合 Span<T> 可进一步零分配)。
  • 多维支持 ‌:数组原生支持多维(int[,]);List<T> 仅一维,嵌套列表效率低且内存不连续。
  • 接口抽象 ‌:对外暴露集合时优先用 IReadOnlyList<T>Span<T>(.NET Core 2.1+),避免泄露具体实现。

选择决策流

  1. 数据量是否‌创建时已知且永不变更 ‌? → ‌‌:用数组
  2. 是否需‌频繁在中间插入/删除 ‌? → ‌ ‌:评估 LinkedList<T> 或保留 List<T>(小数据量可接受 O(n))
  3. 是否需‌动态增长 + 丰富操作 + LINQ ‌? → ‌ ‌:用 List<T>(务必预设容量)
  4. 极端性能敏感(如游戏帧循环、高频交易)且数据固定? → ‌优先数组 ‌,必要时结合 Span<T> 避免拷贝。

注:Array.Resize 本质是新建数组 + 复制,非真正"扩容";避免在高频路径中反复创建集合实例。

相关推荐
LINgZone21 小时前
后端Java编码规范
java·开发语言
阿里嘎多学长2 小时前
2026-08-24 GitHub 热点项目精选
开发语言·程序员·github·代码托管
何以解忧唯有撸码2 小时前
Winform上位机也能写出媲美Avalonia的界面
c#·源码·自定义控件
SLD_Allen2 小时前
Go语言runtime全景
开发语言·javascript·golang
Elastic 中国社区官方博客2 小时前
OpenTelemetry Java 扩展:无需分叉 agent 即可自定义追踪
java·大数据·运维·开发语言·数据库·人工智能·elasticsearch
不灭的黄金瞳1233 小时前
C语言手写顺序表
c语言·开发语言·数据结构
阿无,3 小时前
Java多线程面试题之AQS
java·开发语言
豆沙沙包?3 小时前
C++~~~set容器、map容器(p57-P69)
开发语言·c++