Performance Improving a Sudoku Resolver .net application

In this post, I will investigate how to improve the performance of a sample Sudoku resolver application. The base Sudoku resolver is a .net core console application written in C#. The original source has been written only in a couple of hours, while performance was not the main priority. In this post, I will gradually improve the performance of the application and document the process step-by-step. These articles will also touch on how some of the tools such as PerfView, dotnet-counters and BenchmarkDotNet can be used to measure performance. The goal of the optimization will be to reach a mean execution time below 500 us with a unimodal distribution and minimal allocation per run. By run I mean once the application is started, a run is parsing an input of a Sudoku and providing a solution for it. The application may execute multiple runs during its lifetime as a process. For repeatability of the performance tests, I have chosen a sample Sudoku input that is used throughout all the performance tests.

The goal of this post is to represent the ideas that may be used to optimize applications. I will try to avoid showing huge classes or large code, but I will show slices of the code that is modified in an iterative fashion. At this point, I would like to highlight that I am not optimizing the algorithm to resolve a Sudoku, I am optimizing the code that executes the algorithm to resolve the Sudoku. The algorithm itself will not change throughout the optimization process.

Why does performance matter in these days? In a cloud first, serverless world, where computation is bought on memory and CPU used by our application, we can only serve more request for the save money if our application is efficient - also we end up with a more "environment friendly application" by using less power with potentially less CO2 emissions.

Base Application

Find out more


Inlining Code 2

This post is the second part of a 2 posts long series, discussing inlining in relation to DCE and exception handling.

Introduction

This post is about code inlinig by the JIT compiler and Dead Code Elimination (DCE).

  • Code Inline: call of the method at the callsite is replaced with the invoked method body.

  • DCE: Modern compilers are smart enough to detect code segments, that has no effects, hence they can be removed.

Find out more


Inlining Code

This post is the first part of a 2 posts long series, discussing code inlining in relation to DCE and recursive methods.

Introduction

  • Code Inline: call of the method at the callsite is replaced with the invoked method body.

  • DCE: Modern compilers are smart enough to detect code segments, that has no effects, hence they can be removed.

I will walk to through two examples showing these compiler features in action in regards to exception handling and recursive methods. At this point, I expect the reader to have a good understanding on both of the above compiler features.

Find out more


Updating Rhino Mocks

In the .NET Core era, more-and-more existing .NET applications are getting updated to the new technology stack. Using netstandard libraries the upgrade is relatively simple. On the other hand, using non standard libraries may cause issues. One of the libraries that is not netstandard is Rhino Mocks. Rhino Mocks is used for mocking test dependency behavior. Unfortunately it is not .NET Core compatible, so using Rhino Mocks in tests is blocker to moving along with the .net core stack.

We can do 2 things to overcome such an issue:

  • Update Rhino Mocks by making it .NET Core compatible

  • Move away from Rhino mocks to other mocking libraries

The first point should be an obvious choice, but as it turns out, there are multiple repos for Rhino Mocks, and none of them seems to be the "true" source and none of them seems to be maintained either. That leaves with the second choice.

Find out more


Fixing my classes with NDepend Graph View

NDepend's 2020 release has a new Dependency Graph view. I am keen to try it out, and I just have the prefect project for the test. In this post I will use the Dependency Graph view on one of my most 'messy' projects. The project is started as a Proof Of Concept (POC), then I based 3 other Proof Of Concept apps on it.

This made all namespaces, dependencies and responsibilities mixed. The Visual Studio solution consists of three projects. An ASP.NET Core project of the chatbot implementation, an Azure Functions project for managing IoT devices and a shared library project common types.

NDepend has a VS Extension, which streamlines work a lot, but at the same time it also has standalone executable, which does not require installation. I like these apps, because I can just drop them to my \tools folder and use them as needed. Once I notice that I use an app extensively for a period of time, I can install the VS Extension.

Dependency Graph First View

Find out more