Laszlo

Hello, I am Laszlo

Software-Engineer, .NET developer

Contact Me

IsSorted using SIMD in .NET

Sorting a set or an array is a relatively expensive operation. The costs of sorting typically increase non-linearly with the input size. Therefore, in certain cases, it can be beneficial to check if an array is already sorted before attempting to sort it.

Note: Different sorting algorithms handle sorted or 'nearly sorted' collections with varying degrees of efficiency.

For perspective, sorting an already sorted integer array with a million elements using Array.Sort in .NET takes 5,180.9 us on my machine. In contrast, validating if the same array is sorted takes only 119.0 us. For applications where most input arrays are expected to be sorted, validating sorted-ness first can be a worthwhile optimization.

Similarly, an operation like binary search might want to validate the precondition of the input array being sorted.

Find out more »


Measuring Lock Contention

Scaling multi-threaded applications is often limited by the proportion of the workload that cannot be parallelized. This concept is captured by Amdahl's law. Code sections guarded by locks are a common example — they restrict scalability by allowing only one thread (or n threads in the case of semaphores) to execute, forcing other threads to wait due to lock contention.

Context

In an HTTP/2 server, requests and responses on a connection are multiplexed. The server needs to write concurrently computed responses to a network stream. Such multiplexing can be achieved in multiple ways:

Find out more »


HTTP/3 with ASP.NET Core and browsers

Configure ASP.NET Core WebApi

In this post I explore how to test locally an ASP.NET Core WebApi with HTTP/3 in a local environment using a browser. In ASP.NET Core with .NET 10, HTTP/3 is already supported, but it is an opt-in feature.

To enable HTTP/3, add the following configuration to the application, either in the appsettings.json file

"Kestrel": {
  "EndpointDefaults": {
    "Protocols": "Http1AndHttp2AndHttp3"
  }
}

Find out more »


Know Your Data

There are many social posts, blog posts, and code suggestions online for .NET code snippets titled "Use X instead of Y" or "Why X is better than Y". These posts usually (but not always) include a basic performance comparison using BenchmarkDotNet to validate their catchy titles.

At first glance, these suggestions appear justified by the measurements. However, upon closer inspection, many important details are typically excluded:

  • What version of .NET (SDK and Runtime) was used?
  • What version of OS was used?
  • What is the underlying hardware architecture (ARM or x64)?
  • Does the hardware support vectorized operations?
  • What are the sizes of the vector registers?
  • What is the memory read latency?
  • What are the CPU cache sizes?
  • What branch prediction algorithm does the CPU use?
  • What are the input data types (structs, classes, primitives)?
  • What is the input data structure?
  • What is the size of the input data (bytes/array length)?
  • What is the data access pattern?
  • And many more factors

Since explaining all these factors is beyond this post's scope, I will focus on data access patterns and data sizes. For those interested in a deeper analysis, I recommend reading Pro .NET Benchmarking by Andrey Akinshin, which explains many common pitfalls.

Find out more »


Request Cancellation in ASP.NET Core with HTTP/2

ASP.NET Core allows to create endpoints that receive a cancellation token, such as below:

app.MapGet("/path", async (CancellationToken token) =>
{
});

In this post, I will explore how a server (such as Kestrel) may fire the token to be canceled.

Cooperative Cancellation

Find out more »