Microsoft .NET Source Generators: Speeding up JSON Serialization

One of the big features added to Microsoft .NET 5 was the addition of source generators. A Source Generator is a new kind of component that C# developers can write that lets you do two major things:

  • Retrieve a compilation object that represents all user code that is being compiled. This object can be inspected, and you can write code that works with the syntax and semantic models for the code being compiled, just like with analyzers today.
  • Generate C# source files that can be added to a compilation object during compilation. In other words, you can provide additional source code as input to a compilation while the code is being compiled.

Since my new book “Rock Your Code: Code & App Performance for Microsoft .NET” focuses on performance, I am most interested in these types of generators. In this article, I will be showing the System.Text.Json source generator.

Setting Up the Source Generator

First, we must create a new type using JsonSerializerContext as the base type to set this up. In the code below, part of the benchmarking code for my code performance book, I am creating a context type for PersonProper and List<PersonProper>. PersonProper is one of the main types I use in benchmark testing that can be found in my Spargine OOS.

using System.Text.Json.Serialization;

[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(PersonProper))]
public partial class PersonProperJsonSerializerContext : 
                                 JsonSerializerContext
{}

[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(List<PersonProper>))]
public partial class PersonProperCollectionJsonSerializerContext : 
                                JsonSerializerContext
{}

That’s it! Easy! No need to modify the type that you will be serializing! The main property we will be using is Default as you will see.

Serializing & Deserializing

Serializing and deserializing are simple using System.Text.Json.JsonSerializer is shown below.

Serialize

Here is how to serialize an object.

var json = JsonSerializer.Serialize(person, typeof(PersonProper),
                   PersonProperJsonSerializerContext.Default);

Here is how to serialize a List<>.

var json = JsonSerializer.Serialize(json, typeof(List<PersonProper>), 
                   PersonProperCollectionJsonSerializerContext.Default);

Deserialize

This is how to deserialize JSON for an object.

var person = JsonSerializer.Deserialize(json, typeof(PersonProper),
                       PersonProperJsonSerializerContext.Default) as PersonProper;

This is how to deserialize JSON for a List<>.

var people = JsonSerializer.Serialize(json, typeof(List<PersonProper>),
                       PersonProperCollectionJsonSerializerContext.Default);

Performance

This source generator’s main purpose is to increase performance. Let’s see if that is true. The first chart shows the performance of a reference object (PersonProper from Spargine).

As you can see, using the JSON source generator does improve performance and the bytes allocated.

Allocations:

  • Deserialize – 2,150 to 2,174 bytes
  • Deserialize with generator – 872 to 88 bytes
  • Serialize – 960 – 1,024 bytes
  • Serialize with generator – 1,088 to 1,176 bytes

Now let’s test serialization for a list of ref objects (PersonProper from Spargine) with a count of 100 items.

As you can see, the performance is close.

Allocations:

  • Deserialize – 91,551 to 91,766 bytes
  • Deserialize with generator – 91,393 to 91,528bytes
  • Serialize – 96,893 – 96,889 bytes
  • Serialize with generator – 117,582 to 117,700 bytes

Summary

Using the source generator does improve performance for most of the benchmark tests. I hope that the .NET team at Microsoft will make improvements.

You can find more performance tips for .NET by picking up the 3rd edition of Rock Your Code: Code & App Performance for Microsoft .NET available on Amazon.com.

Please make a comment below. I’d love to hear from you.

Pick up any books by David McCarter by going to Amazon.com: http://bit.ly/RockYourCodeBooks

One-Time
Monthly
Yearly

Make a one-time donation

Make a monthly donation

Make a yearly donation

Choose an amount

$5.00
$15.00
$100.00
$5.00
$15.00
$100.00
$5.00
$15.00
$100.00

Or enter a custom amount

$

Your contribution is appreciated.

Your contribution is appreciated.

Your contribution is appreciated.

DonateDonate monthlyDonate yearly

If you liked this article, please buy David a cup of Coffee by going here: https://www.buymeacoffee.com/dotnetdave

© The information in this article is copywritten and cannot be preproduced in any way without express permission from David McCarter.

2 thoughts on “Microsoft .NET Source Generators: Speeding up JSON Serialization

  1. I’m not sure if I misread the chart, but it looks like using Source Generator actually increased the time of serializing the List object?

    The difference might not be large, but if that’s correct, it seems like we shouldn’t assume that source generators will most likely improve performance. In such case, it might be unreasonable to use them without measuring first. Interesting, I assumed otherwise.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.