Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
Performance in C#: Allocations, Structs and Measuring with BenchmarkDotNet
Why Stopwatch isn't enough, setting up BenchmarkDotNet 0.15.8 and reading its table, the measured difference between classes and structs, hidden allocations from boxing and closures, and benchmark pitfalls.
ref Returns, ref Locals, in Parameters and ref struct in C#
Moving values by reference instead of copying them: ref locals, ref returns, ref readonly, the defensive-copy trap with in parameters, readonly structs and writing your own ref struct.
Span<T> and Memory<T> in C#: Allocation-Free Parsing, stackalloc and ref struct Rules
Copy-free slicing and allocation-free parsing with Span<T>, a measured allocation difference, stackalloc and its safe pattern, ref struct restrictions, and Memory<T> for async code.
C# ValueTask: When to Use It Instead of Task, and Its Rules
An async method that returns synchronously from a cache allocates 72 bytes per call with Task<int>, and nothing with ValueTask<int>. The Debug versus Release measurement gap, the runtime's small-result cache, the cached and truly asynchronous paths in BenchmarkDotNet, the real InvalidOperationException from awaiting a ValueTask twice on a Channel, AsTask, and when to choose ValueTask.
Why Async Exists in C#: Blocking, I/O and Scale
The same 100 stock queries finish in one second with async and in 8-9 seconds with code that blocks the thread. The difference between I/O-bound and CPU-bound work, what blocking costs in a UI and on a server, thread pool starvation, why async buys capacity rather than speed, and the fake async trap.
LINQ and .NET 7–8: Order, ToDictionary Without Selectors and Performance
.NET 7's Order and OrderDescending, which need no key selector, why a missing IComparable only blows up at runtime, culture-sensitive versus ordinal string sorting, .NET 8's selector-less ToDictionary, and vectorized Max/Sum plus Order versus OrderBy(x => x) measured with BenchmarkDotNet.
LINQ Performance: Multiple Enumeration, Materializing and Measuring with BenchmarkDotNet
How many times the same query runs without you noticing, when ToList saves you and when it hurts, Any() instead of Count() > 0 and TryGetNonEnumeratedCount; measuring with BenchmarkDotNet 0.15.8 why a Where inside a loop is 50x slower than a lookup, and comparing loops with LINQ on a noisy machine, with real numbers.
Immutable Collections in C# and Choosing the Right Collection
The difference between a read-only view and real immutability, structural sharing in ImmutableList, builders, ImmutableArray versus ImmutableList measured with BenchmarkDotNet, and choosing the right collection with a complexity map.