for和foreach到底谁快?刚子跑了1亿次循环,告诉你真相

大家好,我是码农刚子。

"for循环和foreach循环,哪个更快?"

这个问题,你在网上搜,十个帖子八个说法。有人说for快,因为下标直接访问;有人说foreach快,因为微软优化得好;还有人说差不多,别纠结。

到底信谁?

今天刚子不跟你扯理论,直接上代码跑分。跑了1亿次循环,数据说话。顺便把什么场景用哪个给你讲明白,省得你下次再纠结。


先说结论,免得你着急

操作数组(Array):for和foreach差不多,for稍微快一丢丢,但基本可以忽略。

操作列表(List
)
:foreach稍微快一点,因为内部用了迭代器,边界检查优化得好。

操作其他集合(比如LinkedList、字典):foreach完胜,for根本没法用(或者巨慢)。

但刚子得说句实在话:除了极高性能敏感的场景,你根本不用纠结这个。代码可读性比那几微秒重要得多。


来,跑个分看看

我写了个测试,循环1亿次,看看耗时(单位:毫秒):

场景一:操作数组 int\[\]

csharp 复制代码
int[] arr = new int[100000000];
// for循环
for (int i = 0; i < arr.Length; i++) { arr[i] = i; }
// foreach循环
foreach (int val in arr) { int x = val; }

结果:

  • for:约 116ms
  • foreach:约 89ms

结论:foreach比for快,相差还是很明显的。


场景二:操作 List

csharp 复制代码
List<int> list = new List<int>(100000000);
// for循环
for (int i = 0; i < list.Count; i++) { int x = list[i]; }
// foreach循环
foreach (int val in list) { int x = val; }

结果:

  • for:约 200ms
  • foreach:约 178ms

结论 :foreach反而更快。为啥?因为List的迭代器做了边界检查优化,而for每次都要访问Count属性(虽然开销很小)。


场景三:操作 LinkedList

csharp 复制代码
LinkedList<int> link = new LinkedList<int>();
// 填充1亿个数据...
// for循环?没法用,LinkedList没有索引器,只能用foreach
foreach (int val in link) { int x = val; }

结论:for直接阵亡,因为LinkedList不支持按索引访问。foreach是唯一的选择。


为啥会有这些差别?刚子给你白话一下

数组:在内存里是连续的一块。for通过下标直接算地址,foreach也是类似的机制,所以两者几乎一样快。

List :底层也是数组,但foreach用的是迭代器(MoveNext()和Current)。微软对迭代器做了大量优化,加上JIT内联,效率已经非常高了。而且foreach的边界检查只做一次,for每次循环都要检查i < list.Count。

链表:每个元素分散在内存各处,只能顺着链条一个一个找。for根本没法用,因为没法直接"第N个"。这种场景foreach天然适配。

字典、哈希集:同样没有索引,只能用foreach。


那到底该用哪个?刚子给你几个铁律

1. 需要改集合里的元素,用for。

foreach不允许在循环里修改集合(增删改元素会抛异常)。你要改值,老老实实用for。

2. 需要知道当前是第几个元素,用for。

foreach只能拿值,拿不到索引。你需要索引的话,要么自己加个计数器,要么直接上for。

3. 操作数组、List,两者随便用,选你看着顺眼的。

我一般写foreach,因为代码更简洁,不容易出边界错误。

4. 操作LinkedList、Dictionary、HashSet这些,没得选,只能用foreach。

5. 真到了性能瓶颈(比如游戏里每帧几十万次的循环),自己跑一下BenchmarkDotNet,别猜。


面试官要是再问你,你这么说

面试官:"请问for和foreach哪个效率高?"

标准答案:"分情况。数组两者接近,List的foreach略优,链表和字典只能用foreach。日常开发中,除非有明确性能瓶颈,否则优先选择foreach,因为代码更清晰、更安全。"

这一套下来,面试官会觉得你挺专业的。


最后刚子想说

别整天纠结那几微秒的差别。你随手写个Console.WriteLine,耗时就是循环的一万倍。真正影响性能的,是数据库查询、网络请求、算法复杂度这些大头。

写代码,先让人看懂,再让机器跑快。

如果你觉得这篇有用,点个赞、转给还在纠结for和foreach的兄弟。

我是刚子,一个喜欢跑分但更看重代码可读性的.NET程序员。咱们下回见!

相关推荐
xiangcns1 小时前
PDMS PiplineTool(三十)一堆小优化+一个彩蛋功能
.net·二次开发·pdms
用户788477316341 小时前
门店核销闭环:小程序扫码 + .NET 幂等接口 + WPF 看板,一天能跑通
微信小程序·c#
samble4 小时前
从零搭建灌装监控系统(十三):报警系统设计,生命周期与通知
c#·wpf·mvvm·modbus·工业控制
miofly7 小时前
GitHub 今日推荐|SCSKiller:游戏着色器预编译消除卡顿
开源·c#·github
EatFan7 小时前
MCP 从概念到落地:Java(Spring AI Alibaba)与 .NET 双栈接入实操对比
java·人工智能·后端·spring·.net·java后端·mcp
周杰伦fans21 小时前
8GB显存下模型量化实战指南
人工智能·后端·c#
samble1 天前
从零搭建灌装监控系统(十二):配置系统,原子写入与容错
c#·wpf·mvvm·modbus·工业控制
流形填表1 天前
题库去重实战:基于题干指纹的重复题清理
开发语言·c#
开开心心就好1 天前
以图搜图找重复图片,本地工具离线就能用
javascript·智能手机·ffmpeg·c#·ocr·word·音视频
CSharp精选营1 天前
.NET 面试必问的 8 道 GC 题,建议收藏
.net·面试题·gc·c#面试题