Nov 7, 2022

A small C# 10 programming puzzle - Answer (Part II)

Leia este post em português

Lire cet post en Français.

In the last post I've posed a challenge to change the output of the following program to show only lines with even numbers.

The only caveat is that I've restricted what could be changed as follow:

  1. You could not  change Foo's  implementation in any way other than changing its msg parameter type.
  2. You could not change the implementation of the for loop in any ways.
  3. You could not on IL post-processing in any way (but it would be a nice exercise 😃)
  4. Any other changes to the source are acceptable

I've also said that if you look carefully in the code you would be able to find some clues on the direction of the solution (at least the one I was thinking about) based on pieces of code that were non essential. I'll come back to those later but first let me quickly introduce a C# feature that has been around since C# 6 that will be used in my final solution: Interpolated strings.

Interpolated strings are strings literals prefixed with $ character and containing C# expressions wrapped in braces ({ ... }) for which C# compiler will emit code to replace such expressions with their respective values; the main idea is to simplify string formatting code. For example, in the program below:

C# compiler will replace {i} with the value of variable i and {args[i]} with the value of the element at index i of the args array.

When the support for interpolated strings was first introduced the compiler would emit code similar to:

Or, in other words, it would replace the interpolated string with one or more calls to String.Format()(as show in line #10 above). There's nothing wrong with that, after all, that is almost exactly the code a developer would write in the absence of interpolated string support, but with the push for performance in the recent years, the .NET developers realized that there was some margin for improvements in that area; indeed, if you look into the code above, there are a couple of non-ideal code, memory wise:

  1. In line #5, there's an array allocation.
  2. There are 3 boxing operations (lines #6, 7 & 8)
  3. String.Format() method will likely end up calling Int32.ToString() which will allocate a new string (at least on some versions of .NET).
In small (or even medium ?) programs that would barely make any difference, but on bigger applications making heavily use of string manipulation that proved to be a potential source of performance issues so in C# 10 the concept of string interpolation handlers, the subject of the next post, was introduced to address some of those.

Have fun!

Adriano

No comments: