The fastest way to iterate a List in C# is NOT what you think



Check out my courses: https://nickchapsas.com
Become a Patreon and get source code access: https://www.patreon.com/nickchapsas

Hello everybody I’m Nick and in this video I will show you all the way you can iterate a List in C# and then show you what is by far the fastest and most memory efficient way. You might have guessed where this is going 🙂

Don’t forget to comment, like and subscribe 🙂

Social Media:
Follow me on GitHub: http://bit.ly/ChapsasGitHub
Follow me on Twitter: http://bit.ly/ChapsasTwitter
Connect on LinkedIn: http://bit.ly/ChapsasLinkedIn

Keep coding merch: https://keepcoding.shop

#csharp #dotnet

36 Comments

  1. When a program's performance tests are below client's expectations, would you always go for a Span<> refactorization?
    …assuming that no major blunder was made like a bad algorithmic complexity.

  2. You can't mutate the collection in any foreach anyway so there's no downside to using the span method it would seem to me. So if you need to mutate the list you're using for instead of foreach anyway and just can't use the span.

    Very cool!

  3. Getting a local scoped reference to the array allows JIT to optimize away the range checks in the loop (technically also unroll but I don't think it does that). It's not possible for a list since there is no guarantee that other code somewhere wont change the length during our looping. But if you have an array, then length is fixed, and you can do a single if-check pre-looping instead of checking the bounds every iteration.

  4. I discovered that you should avoid using list in the first place, especially for "returning" list of things.. Passing a delegate (a callback) to your list generator and having it calling the callback is much faster that storing a list and iterating it after. Plus you can generically transform delegate (for instance transform any delegate into a filtering delegate that calls or don't call the first one)

  5. Yeah, makes sense the Span way would be the fastest, since if I understand correctly, span should be a continuous slice of memory, meaning after it's loaded it should have literally zero cache misses and literally just linear memory access for every item, which can't be guaranteed for any of the other methods.
    (Correct me if i'm wrong)

  6. Didn’t know about Span(), never would have thought to look, foreach was already heaven, thank you.
    I was taught never add or remove items during a for loop but dd it anyway, then fast forward to writing multithreaded applications and foreach and Span() throwing an exception is a useful indicator of faulty design.

  7. I use Parallel when the tasks are small in number and heavy. I have an app that does six similar tasks, each taking about 500 ms, and it's great. If you needed 3000 ms instead by doing 3000 tasks that each take 1 ms, the overhead of creating each instance makes it a close call. If it's 3,000,000 jobs that each take 1 us, then I definitely would not parallel.

  8. Foreach is faster than a for loop if the list contains reference types.
    Just avoid lists whenever you can, arrays are much better when applicable, and they allow you to use stuff like Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(ref array), index) if you really really need to skip those pesky bound checks when the JIT can't remove them itself (obviously, you'd better know what you're doing !).

  9. I see alot of comments from people trying to learn c#, take note this video is 100% wrong. Linq is 1k times faster and with the new updates in .net 7 its even faster. The problem is he is not using linq correctly. Normally I wouldn't comment but if your going to have a video aimed at teaching it should be right.

  10. I wonder if you know, that Microsoft did implemented an implicit cast for ReadOnlySpan which is safe then:
    [Benchmark]

    public void Foreach_Span()

    {

    System.ReadOnlySpan<int> spanList = CollectionsMarshal.AsSpan(_list);

    foreach (int item in spanList)

    {

    }

    }

Leave a Reply

© 2023 53GB