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程序员。咱们下回见!

相关推荐
雪人不是菜鸡14 小时前
反射调用方法
c#
unicrom_深圳市由你创科技19 小时前
C# 如何实现对象序列化
开发语言·c#
成都易yisdong20 小时前
实现三北方向转换计算器(集成 WMM2025 地磁模型)
开发语言·windows·算法·c#·visual studio
guygg8821 小时前
OPC UA Helper: 连接PLC获取变量值
服务器·网络·c#
light blue bird1 天前
主从执行端动机模块工序协同组件
jvm·数据库·.net·桌面端
成都易yisdong1 天前
基于C#和WMM2025模型的地磁参数计算器实现
开发语言·c#