C# 15 memory allocation benchmarks
with() syntax, mostly because I’ve spent the last week realizing my "clean" prototyping code is actually a performance nightmare waiting to happen. I decided to stop being lazy and actually benchmark the overhead of dynamic resizing versus explicit capacity, because apparently, my intuition about "small delays" was laughably wrong.I set up a local test to see how much of a mess I was making. I ran a loop to push 100,000 integers into three different list implementations. I wanted to see if the new collection expression syntax would actually be a disaster or if the compiler was actually doing something smart for once.
Here is the exact snippet I used to embarrass myself:
using System.Diagnostics;const int Size = 100_000;
var sw = new Stopwatch();
// The "lazy" way
sw.Restart();
List<int> noCap = new();
for (int i = 0; i < Size; i++) noCap.Add(i);
sw.Stop();
Console.WriteLine($"No capacity: {sw.ElapsedMilliseconds} ms");
// The traditional pre-allocation
sw.Restart();
List<int> withCap = new(Size);
for (int i = 0; i < Size; i++) withCap.Add(i);
sw.Stop();
Console.WriteLine($"Manual capacity: {sw.ElapsedMilliseconds} ms");
// The new C# 15 way
sw.Restart();
List<int> modern = [with(capacity: Size), ..Enumerable.Range(0, Size)];
sw.Stop();
Console.WriteLine($"C# 15 with(capacity): {sw.ElapsedMilliseconds} ms");
The results were a total reality check. The standard noCap approach—where the list just keeps re-allocating memory every time it hits a limit—was incredibly slow. It’s basically just a massive amount of wasted CPU cycles spent on memory management.
The real shocker, though, was the with(capacity: Size) syntax. I expected it to be some bloated syntactic sugar that would tank performance, but it was actually the fastest method in the bunch. It’s weirdly elegant; it doesn't look like some desperate performance hack you'd find in a legacy codebase. It just looks like proper, idiomatic C#. If you’re working with anything larger than a tiny dataset, you should probably stop guessing and just write a quick console app to see the delta. It turns out that being "modern" doesn't have to mean being slow.