Span<T> and Memory<T> Are Your Friends
For tight loops over contiguous data, Span<T> avoids heap allocations entirely. Combined with stackalloc for small buffers you can write high-performance code that is still readable and safe.
LINQ is beautiful but it is not free. Let's talk about when it hurts and what to reach for instead.
For tight loops over contiguous data, Span<T> avoids heap allocations entirely. Combined with stackalloc for small buffers you can write high-performance code that is still readable and safe.
Counterpoint: unless you are writing game engines or trading systems, LINQ allocations are noise compared to network I/O, database calls, and JSON serialization. Optimize the actual bottleneck, not the pretty query syntax.
Every LINQ chain allocates enumerator objects on the heap. In a hot path called thousands of times per second this matters. Use BenchmarkDotNet to measure before assuming LINQ is the bottleneck, but know that for loops over arrays are often 5-10x faster.
The sneaky LINQ performance trap in C# is mixing EF Core queryables with in-memory LINQ. If you call .ToList() too early, you pull the entire table into memory and filter it in C#. Use EF Core's async queryable methods and only materialize at the last step.