<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/how-to-loop-through-a-list-in-c-every-way-benchmarked-zbn9k4tj3" -->

---
title: How to Loop Through a List in C#: Every Way, Benchmarked
description: Looping over a List<T> in C# has several options, and foreach and for tie in speed within 2% of each other on lists of 1,000 and 100,000 items....
canonical: https://daily.dev/posts/how-to-loop-through-a-list-in-c-every-way-benchmarked-zbn9k4tj3
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: How to Loop Through a List in C#: Every Way, Benchmarked | daily.dev
og:description: Looping over a List<T> in C# has several options, and foreach and for tie in speed within 2% of each other on lists of 1,000 and 100,000 items....
og:url: https://daily.dev/posts/how-to-loop-through-a-list-in-c-every-way-benchmarked-zbn9k4tj3
og:image: https://api.daily.dev/og/posts/ZbN9K4tj3.png
og:image:alt: How to Loop Through a List in C#: Every Way, Benchmarked
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# How to Loop Through a List in C#: Every Way, Benchmarked

**[Khalid Abuhakmeh](https://daily.dev/sources/khalidabuhakmeh)** · 11 min read · 20 upvotes · 1 comments

## Summary

Looping over a List<T> in C# has several options, and foreach and for tie in speed within 2% of each other on lists of 1,000 and 100,000 items. CollectionsMarshal.AsSpan is the fastest, running 21% to 26% faster than for because it skips bounds checks on the backing array. List<T>.ForEach is about 1.5x slower due to delegate calls and closure allocation. Enumerable.Index() is about 5.6x slower and allocates 104 bytes per call. Benchmarks ran on .NET 10.0.12 and .NET 11 RC 1 on an Apple M4 Pro, and .NET 11 performs within 4% of .NET 10 at larger sizes.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://khalidabuhakmeh.com/posts/how-to-loop-through-a-list-in-csharp>

## Questions this post answers

### Is a for loop faster than a foreach loop for a List<T> in C#?

No, they run at essentially the same speed on a List<T>. Benchmarks on .NET 10.0.12 and .NET 11 RC 1 show for and foreach finishing within 2% of each other at 1,000 and 100,000 items, because the JIT optimizes foreach over a List<T> as well as it optimizes for. Use foreach by default unless you need the index.

_Comparing loop performance before optimizing C# code? Track benchmarks like these on daily.dev._

### How much faster is CollectionsMarshal.AsSpan than a regular for loop over a List<int> in C#?

CollectionsMarshal.AsSpan runs 21% to 26% faster than a for loop at 1,000 items and up, because it loops directly over the list's backing array and skips the indexer's bounds checks. At 100,000 items, AsSpan took about 27.19 microseconds versus 35.49 microseconds for a for loop on .NET 11 RC 1.

_Developers chasing hot-path performance in C# can keep benchmarks like this handy on daily.dev._

### Why does List<T>.ForEach allocate memory when the lambda captures a variable?

Because each call allocates a closure to hold the captured variable, costing 24 bytes per call in the benchmark where the lambda captured a sum variable. This also makes List<T>.ForEach about 1.5 times slower than a plain for or foreach loop, since each item invokes a delegate call on top of the allocation.

_Anyone debugging unexpected allocations in C# loops can revisit findings like this on daily.dev._

## Community discussion

Top comments from developers on daily.dev.

**@f4nt0** · 1 upvotes

> Even in the AI era I still like to see posts about language informations and usages. Keep the good work!

## Similar posts on daily.dev

- [Making foreach on an IEnumerable allocation-free using reflection and dynamic methods](https://daily.dev/posts/making-foreach-on-an-ienumerable-allocation-free-using-reflection-and-dynamic-methods-cmewcz0u9) · .NET Escapades · 1 upvotes · 0 comments
- [Improve C\# code performance with Span<T>](https://daily.dev/posts/improve-c-code-performance-with-span-t--iyv8npksm) · NDepend Blog · 1 upvotes · 0 comments
- [Array Sort Extensions and Benchmarking: Measuring 2D and Jagged Array Optimized Sort Extensions Performance Against LINQ](https://daily.dev/posts/array-sort-extensions-and-benchmarking-measuring-2d-and-jagged-array-optimized-sort-extensions-perf-womocamjc) · C\# Corner · 0 upvotes · 0 comments

---

Tags: [#performance](https://daily.dev/tags/performance), [#.net](https://daily.dev/tags/.net), [#c#](https://daily.dev/tags/c#)

[View this post on daily.dev](https://daily.dev/posts/how-to-loop-through-a-list-in-c-every-way-benchmarked-zbn9k4tj3)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"How to Loop Through a List in C#: Every Way, Benchmarked","url":"https://daily.dev/posts/how-to-loop-through-a-list-in-c-every-way-benchmarked-zbn9k4tj3","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/how-to-loop-through-a-list-in-c-every-way-benchmarked-zbn9k4tj3"},"datePublished":"2026-10-27T14:29:02.005Z","dateModified":"2026-10-27T14:29:33.191Z","description":"Looping over a List\u003cT\u003e in C# has several options, and foreach and for tie in speed within 2% of each other on lists of 1,000 and 100,000 items....","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/f5595f83aea3b44c92b5eb0e265b7e71?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/f5595f83aea3b44c92b5eb0e265b7e71?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Khalid Abuhakmeh","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Khalid Abuhakmeh","logo":"https://media.daily.dev/image/upload/s--DwEMyeUp--/f_auto,q_auto/v1780213469/logos/khalidabuhakmeh?_a=BAMAMiWQ0","url":"https://daily.dev/sources/khalidabuhakmeh"},"commentCount":1,"discussionUrl":"https://daily.dev/posts/how-to-loop-through-a-list-in-c-every-way-benchmarked-zbn9k4tj3","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":20},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":1}],"keywords":"performance,.net,c#","timeRequired":"PT11M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Khalid Abuhakmeh","item":"https://daily.dev/sources/khalidabuhakmeh"},{"@type":"ListItem","position":3,"name":"How to Loop Through a List in C#: Every Way, Benchmarked"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/how-to-loop-through-a-list-in-c-every-way-benchmarked-zbn9k4tj3","comment":[{"@type":"Comment","text":"Even in the AI era I still like to see posts about language informations and usages. Keep the good work!","datePublished":"2026-10-30T17:44:20.530Z","url":"https://daily.dev/posts/ZbN9K4tj3#c-c7Qz9VfZ8","author":{"@type":"Person","name":"Gabriel Stundner","url":"https://daily.dev/f4nt0","image":"https://media.daily.dev/image/upload/s--UpSzkOxs--/f_auto/v1753488097/avatars/avatar_whNNg0ajcmne1B7hPHb0U?_a=BAMClqZW0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/how-to-loop-through-a-list-in-c-every-way-benchmarked-zbn9k4tj3#faq","mainEntity":[{"@type":"Question","name":"Is a for loop faster than a foreach loop for a List\u003cT\u003e in C#?","acceptedAnswer":{"@type":"Answer","text":"No, they run at essentially the same speed on a List\u003cT\u003e. Benchmarks on .NET 10.0.12 and .NET 11 RC 1 show for and foreach finishing within 2% of each other at 1,000 and 100,000 items, because the JIT optimizes foreach over a List\u003cT\u003e as well as it optimizes for. Use foreach by default unless you need the index. Comparing loop performance before optimizing C# code? Track benchmarks like these on daily.dev."}},{"@type":"Question","name":"How much faster is CollectionsMarshal.AsSpan than a regular for loop over a List\u003cint\u003e in C#?","acceptedAnswer":{"@type":"Answer","text":"CollectionsMarshal.AsSpan runs 21% to 26% faster than a for loop at 1,000 items and up, because it loops directly over the list's backing array and skips the indexer's bounds checks. At 100,000 items, AsSpan took about 27.19 microseconds versus 35.49 microseconds for a for loop on .NET 11 RC 1. Developers chasing hot-path performance in C# can keep benchmarks like this handy on daily.dev."}},{"@type":"Question","name":"Why does List\u003cT\u003e.ForEach allocate memory when the lambda captures a variable?","acceptedAnswer":{"@type":"Answer","text":"Because each call allocates a closure to hold the captured variable, costing 24 bytes per call in the benchmark where the lambda captured a sum variable. This also makes List\u003cT\u003e.ForEach about 1.5 times slower than a plain for or foreach loop, since each item invokes a delegate call on top of the allocation. Anyone debugging unexpected allocations in C# loops can revisit findings like this on daily.dev."}}]}
```

