Small .NET benchmarks that answer performance questions with measured numbers, not guesses. Each numbered folder is one investigation; findings are published in that folder's README.
Question: Does AsParallel() make LINQ OrderBy faster?
What we measured: sequential OrderBy vs PLINQ OrderBy on int[] and Product[], at 1M and 5M items.
What we found: on those large inputs, PLINQ was faster — about 2.3x for int[] and 1.8x for Product — but used about 5x more memory.
Takeaway: AsParallel() pays off when the input is large enough that parallel work outweighs the setup cost. On small collections the thread/partition overhead often makes it slower. Prefer it for big in-memory sorts when speed matters and you can afford the RAM; keep sequential LINQ when the dataset is small or memory/GC is the constraint.
BenchmarkDotNet prints a table after each run. Here is what each column means:
- Method — which code path was timed (for example sequential vs parallel).
- Count — how many items were in the dataset for that row.
- Mean — average time for one run. Lower is faster. This is usually the first number you look at.
- Error — how uncertain the Mean is. BenchmarkDotNet repeats the work many times; Error is half of a very strict confidence interval around the Mean. If Error is large compared to Mean, treat the result as less trustworthy and re-run with a quieter machine.
- StdDev — how much individual runs differed from each other. Low StdDev means stable timing. High StdDev means noise (background apps, thermal throttling, GC spikes).
- Ratio — speed compared to the baseline method (
Baseline = truein code — here, always*_Sequential_OrderBy).1.00= same speed,0.50= about 2x faster,1.30= 30% slower. - RatioSD — how stable that Ratio was across runs. Lower is better.
- Gen0 / Gen1 / Gen2 — how often the garbage collector ran (per 1,000 operations). Some Gen0 is normal. Lots of Gen2 usually means longer-lived objects and more memory pressure.
- Allocated — how much managed memory one run allocated. Lower is better when two methods produce the same result.
- Alloc Ratio — Allocated compared to the baseline.
5.00means about 5x more memory than the sequential path.
Requires the .NET 10 SDK. Always use Release.
dotnet run --project Runner -c ReleaseThe Runner opens a menu to select a benchmark. Raw HTML/CSV/log output goes to BenchmarkDotNet.Artifacts/ (gitignored).
- Create a numbered root folder such as
02-SomeTopic. - Add a class library with BenchmarkDotNet and the benchmark types.
- Reference it from
Runnerand register its assembly inRunner/Program.cs. - Put the finding at the top of the test README; keep tables and design notes below.