Faster Bound Checks

In a recent pull request I received some comments on how to do bound checks better when indexing into arrays. The original code received a span and an index (scan). If the index was larger to the span's length, it returned minus one. Otherwise it indexes into the buffer and does a further lookup.

private static int ReadHex(int scan, ReadOnlySpan<char> buffer)
{
    if (scan >= buffer.Length)
        return -1;
    int c = buffer[scan];
    return c >= CharToHexLookup.Length ? -1 : CharToHexLookup[c];
}

After implementing the suggestion, the code looks nearly identical, but it is using uint types for the comparing the index variable with the length of the bugger:

private static int ReadHex(int scan, ReadOnlySpan<char> buffer)
{
    if ((uint)scan >= (uint)buffer.Length)
        return -1;
    int c = buffer[scan];
    return c >= CharToHexLookup.Length ? -1 : CharToHexLookup[c];
}

Find out more


A Better way to Automate with Alexa

Recently a started a new habit: I take a train in the mornings to get to the office to work. The train comes at every half an hour, which means I don't want to miss it. To be on the safe side, I had to come up with a solution. The route to the train station is well predictable, it just a few minutes on foot. Trains usually, don't come early so the only variable left is the waiting time on the elevator. After all, the minimum and maximum time to get to the station is within narrow boundaries.

Initial Approach

I decided that some sort of a reminder could help to remind to get going on time. To create a reminder to leave, the simplest and easiest solution is to set an alarm exactly 10 minutes before the train usually arrives to the station. However, I am not a fan of the solution as if the alarm goes off, I have to manually disarm it, which is an extra effort to do, when I should prepare for leaving the flat.

Notifications

Find out more


JsonMergePatch and .NET6

In a previous post I have shown how JsonMergePatch library can be used with console and Asp.Net Core applications.

In this post I will focus on using it with the source generator hand-in-hand of System.Text.Json. Before getting into the details, a new [Patchable] attribute is introduced ease the work:

Patchable

Certain use-cases require to generate wrapper types with the source generation for assemblies that do not directly use Patch<T> (where T is the wrapped source type). This could be a reason for having separate assemblies for entity types, or because of the need of stacking multiple source generators on top of each other.In this case types may be attributed with [Patchable] attribute:

Find out more


WaitAsync

.NET 6 has a new method added to System.Threading.Tasks.Task to wait for a task completion or timeout. WaitAsync method completes with the result of the task it is invoked on, or throws a timeout exception when the given timeout reached or throws a TaskCancelledException if the given cancellation token is set to cancelled state.

The method's primary use-case is to add cancellation or timeout ability for async methods, that inherently don't provide such capability. One use-case could be unit tests, where we explicitly want to time out and fail a test if the method invoked as the system under test is an async operation without a timeout overload. This way we can let other tests to be executed in the test suite.

Previously a poor man (woman)'s implementation for such timeout could look as:

public static async Task<T> TimeoutAfter<T>(this Task<T> task, TimeSpan timeout)
{
    if (task.IsCompleted)
        return await task;
    var cts = new CancellationTokenSource();
    if (task == await Task.WhenAny(task, Task.Delay(timeout, cts.Token)))
    {
        cts.Cancel();
        return await task;
    }
    else
    {
        throw new TimeoutException();
    }
}

Find out more


Math Sin with SIMD

Introduction

In this post I will look into how someone can implement Sin/Cosin functions with SIMD in NET 5. NET 5 does not have a wrapper on SIMD trigonometric functions, so it seems a good exercise to implement it.

Using SIMD, one may gain performance advantage on large data sets. Later in this post I will run a performance benchmark to compare the SIMD implementation with Math.Cos() and MathF.Cos() methods.

Considerations

Find out more