I was profiling a request handler last week and the gen0 line on the allocation chart kept ticking up on a path that, as far as I could tell, allocated nothing. No LINQ, no string building, nothing getting new -ed up. Just a little helper I'd written to pick the largest of a few timeout values, something like PickTimeout(configTimeout, retryTimeout, defaultTimeout) .
The helper took params int[] . That was the whole problem.
Here's the thing I'd managed to forget: every time you call a params method with loose arguments, the compiler builds an array to carry them. PickTimeout(a, b, c) quietly compiles to PickTimeout(new[] { a, b, c }) . One array per call. On a path that runs a handful of times per request, that's nothing you'll ever notice. Mine sat inside a per-row loop, so it ran a lot.
So I did what I always do when a number smells wrong: boiled it down to the dumbest benchmark that still shows the effect and ran it.…