Поиск  
Always will be ready notify the world about expectations as easy as possible: job change page
May 6

.NET performance analysis: Newtonsoft.Json vs System.Text.Json in .NET 8

.NET performance analysis: Newtonsoft.Json vs System.Text.Json in .NET 8
Автор:
Источник:
Просмотров:
2169

Introduction

As a passionate .NET developer, I find myself continuously seeking opportunities to expand my understanding of the .NET ecosystem. In this, my first article ever, I embark on a journey to explore the intricacies of .NET performance, with a specific focus on two prominent JSON frameworks: Newtonsoft.Json and Microsoft’s System.Text.Json. My goal is to share the insights and revelations gained during this exploration with fellow developers who, like me, are keen on deciphering the nuances within our tech ecosystem.

This article is inspired by Tobias Streng’s noteworthy article on .NET 7 performance and I’ve tailored my investigation to align with the latest advancements in .NET 8. Join me on this quest as we uncover the nuances between these two JSON powerhouses and gain a deeper understanding of their performance implications in real-world scenarios.

Original Article: .NET Performance #2: Newtonsoft vs. System.Text.Json by Tobias Streng

Framework Popularity

As of January 27th, 2024, Newtonsoft.Json boasts an impressive record of over 4.2 billion downloads, securing its position as the most downloaded package on NuGet. In contrast, System.Text.Json lags behind with approximately 1.8 billion downloads. Notably, System.Text.Json’s inclusion as a default in the .NET SDK since .NET Core 3.1 significantly contributes to its widespread adoption.

Comparing these numbers to the original .NET 7 article reveals a compelling narrative. At that time, Newtonsoft.Json had accumulated 2.3 billion downloads, signifying an 82.6% increase in download count over the 15-month period. In the same timeframe, System.Text.Json experienced a remarkable growth of 200%, suggesting a faster pace of adoption. However, when examining the sheer download numbers, Newtonsoft.Json added a staggering 1.9 billion downloads in this period — surpassing the total downloads for System.Text.Json since its introduction into the .NET SDK in 2019.

Benchmark Scenarios

To recreate the same scenarios as the original article, we’ll focus on two main use cases:

  1. Serialization and deserialization of a single large dataset.
  2. Serialization and deserialization of many small datasets.

For test data, we will leverage the NuGet package Bogus to generate random users with their own unique identity.

[Params(10000)]
public int Count { get; set; }

private List<User> testUsers =  [ ];

[GlobalSetup]
public void GlobalSetup()
{
    var faker = new Faker<User>().CustomInstantiator(
        f =>
            new User(
            Guid.NewGuid(),
            f.Name.FirstName(),
            f.Name.LastName(),
            f.Name.FullName(),
            f.Internet.UserName(f.Name.FirstName(), f.Name.LastName()),
            f.Internet.Email(f.Name.FirstName(), f.Name.LastName())
            )
    );

    testUsers = faker.Generate(Count);
}

Benchmark Setup

  • Newtonsoft.Json 13.0.3
  • System.Text.Json 8.0.1
  • Bogus 35.4.0
  • BenchmarkDotNet 0.13.12

Serialization Benchmarks

Serialize Big Data Object

In this benchmark, we examine the serialization performance of a single large object using the List<User> data structure. Both frameworks utilize the default ContractResolver.

[Benchmark]
public void NewtonsoftSerializeBigData() =>
    _ = Newtonsoft.Json.JsonConvert.SerializeObject(testUsers);

[Benchmark]
public void MicrosoftSerializeBigData() =>
    _ = System.Text.Json.JsonSerializer.Serialize(testUsers);

Results:

Big Data Method Count Mean Ratio Allocated Alloc Ratio
Newtonsoft 10000 9.415 ms 1.00 8.07 MB 1.00
Microsoft 10000 5.543 ms 1.00 3.42 MB 1.00

The results mirror those found in the .NET 7 analysis, where System.Text.Json outperforms Newtonsoft.Json by over twice the speed. Microsoft’s package also exhibits superior memory efficiency, using less than half the memory compared to Newtonsoft.Json.

Serialize Big Data Object With Custom Json Serializor Settings

In this scenario, we revisit the previous serialization test, introducing a new element: converting the JSON properties to snake case. Note that:

instantiating the ContractResolver more than once can incur a performance hit, so careful consideration is needed.

[Benchmark]
public void NewtonsoftSerializeBigDataWithSettings()
{
    var settings = new Newtonsoft.Json.JsonSerializerSettings()
    {
        Formatting = Newtonsoft.Json.Formatting.Indented,
        ContractResolver = new DefaultContractResolver
        {
            NamingStrategy = new SnakeCaseNamingStrategy()
        }
    };

    _ = Newtonsoft.Json.JsonConvert.SerializeObject(testUsers, settings);
}

[Benchmark]
public void MicrosoftSerializeBigDataWithSettings()
{
    var settings = new JsonSerializerOptions()
    {
        WriteIndented = true,
        PropertyNamingPolicy = new SnakeCasePropertyNamingPolicy()
    };

    _ = System.Text.Json.JsonSerializer.Serialize(testUsers, settings);
}

Results:

Big Data With Settings Method Count Mean Ratio Allocated Alloc Ratio
Newtonsoft 10000 14.093 ms 1.00 10.24 MB 1.00
Microsoft 10000 7.036 ms 1.00 4.48 MB 1.00

The results indicate that both Newtonsoft.Json and Microsoft’s System.Text.Json experience a performance hit and increased memory usage when applying a custom naming policy. However, Newtonsoft.Json shows a more significant increase in mean execution time (4.678 ms) compared to System.Text.Json (1.493 ms), suggesting that Newtonsoft.Json takes approximately 213% more time to execute than Microsoft’s package when applying the same naming policy.

Serialize Many Small Data Objects

This scenario represents a realistic use-case for JSON serialization, closely simulating REST APIs. The benchmark involves looping through the List<User> and serializing each user individually.

[Benchmark]
public void NewtonsoftSerializeIndividualData()
{
    foreach (var user in testUsers)
    {
        _ = Newtonsoft.Json.JsonConvert.SerializeObject(user);
    }
}

[Benchmark]
public void MicrosoftSerializeIndividualData()
{
    foreach (var user in testUsers)
    {
        _ = System.Text.Json.JsonSerializer.Serialize(user);
    }
}

Results:

Individual Data Method Count Mean Ratio Allocated Alloc Ratio
Newtonsoft 10000 7.032 ms 1.00 17.14 MB 1.00
Microsoft 10000 4.870 ms 1.00 3.64 MB 1.00

As observed, Microsoft’s System.Text.Json once again demonstrates faster mean execution time compared to Newtonsoft.Json. Additionally, it is important to note the significant difference in memory allocation between the two packages. Tobias Streng emphasizes the importance of saving heap memory, considering its impact on overall application performance.

“saving heap memory is even more important than the speed, you are seeing here. Heap memory will eventually have to be garbage collected, which will block your entire application from executing”

Deserialization Benchmarks

Deserialize Big Data Object

Now, we’ll shift our focus to deserialization, starting with a benchmark for deserializing one large JSON string into the respective .NET object List<User>.

[Benchmark]
public void NewtonsoftDeserializeBigData() =>
    _ = Newtonsoft.Json.JsonConvert.DeserializeObject<List<User>>(serializedTestUsers);

[Benchmark]
public void MicrosoftDeserializeBigData() =>
    _ = System.Text.Json.JsonSerializer.Deserialize<List<User>>(serializedTestUsers);

Results:

Big Data Method Count Mean Ratio Allocated Alloc Ratio
Newtonsoft 10000 26.363 ms 1.00 10.55 MB 1.00
Microsoft 10000 15.020 ms 1.00 5.92 MB 1.00

Notably, comparing Newtonsoft to Microsoft in deserialization, there haven’t been substantial changes over the past year. While Microsoft appears to have made small optimizations in memory allocation, the overall trend indicates that Microsoft is much faster than Newtonsoft.

Deserialize Many Small Data Objects

Finally, we’ll benchmark the deserialization of many small objects from a List<string>.

[Benchmark]
public void NewtonsoftDeserializeIndividualData()
{
    foreach (var user in serializedTestUsersList)
    {
        _ = Newtonsoft.Json.JsonConvert.DeserializeObject<User>(user);
    }
}

[Benchmark]
public void MicrosoftDeserializeIndividualData()
{
    foreach (var user in serializedTestUsersList)
    {
        _ = System.Text.Json.JsonSerializer.Deserialize<User>(user);
    }
}

Results:

Individual Data Method Count Mean Ratio Allocated Alloc Ratio
Newtonsoft 10000 15.974 ms 1.00 35.5 MB 1.00
Microsoft 10000 8.472 ms 1.00 3.96 MB 1.00

Once again, Microsoft demonstrates nearly twice the speed and astonishingly requires over 30 MB less than Newtonsoft for deserialization. This echoes the findings of the .NET 7 benchmark, indicating a consistent performance advantage for Microsoft. Additionally, it seems that Microsoft has made further optimizations, using slightly less memory than last year.

Conclusion

In the realm of JSON serialization and deserialization within the .NET 8 landscape, our benchmarks present a compelling case. Despite claims of high performance from Newtonsoft.Json, the results unequivocally demonstrate that Microsoft’s System.Text.Json consistently outperforms its counterpart. Whether handling large or small datasets, System.Text.Json showcases superior speed and memory efficiency.

Key Takeaways:

  • Serialization and Deserialization Performance: System.Text.Json consistently excels in both serializing and deserializing tasks.
  • Memory Efficiency: The SDK-native package, System.Text.Json, not only outpaces Newtonsoft.Json in speed but also demonstrates remarkable efficiency in memory allocation.

These findings are specific to .NET 8, and it’s important to recognize that performance characteristics may vary with different versions. Building upon the insights gained from .NET 7, it’s reasonable to assert that System.Text.Json stands as the faster choice in all tested scenarios for .NET 7 and 8. While assumptions about future versions remain uncertain, the recent alignment of the creator of Newtonsoft.Json with Microsoft suggests a potential trajectory favoring System.Text.Json.

You can explore all the benchmark code used in this article on my GitHub repository: https://github.com/TrevorMcCubbin/DotnetBenchmarks

• • •

Original Article: .NET Performance #2: Newtonsoft vs. System.Text.Json by Tobias Streng

Похожее
Oct 25, 2023
Author: Ignacio Chiazzo
As a developer, which areas should we focus on for performance optimizations? How can we measure the impact? Read this post to learn the framework. Performance optimization is any software or hardware modifications that make the platform faster and more...
Apr 4
Author: João Simões
Performance comparison between ToList and ToArray Ever since Microsoft introduced Language Integrated Query to the .NET framework (also known as LINQ) developers have been using it extensively to work with collections. From a simple filter, to an aggregation, to a...
Jul 16, 2021
Author: Edward Pollack
Monitoring SQL Server for performance is a critical part of a DBA’s job. In this article, Edward Pollack explains some of the SQL Server performance monitor data and how to collect it. Windows collects a wide array of useful metrics...
24 марта
Кадр из сериала “Друзья” Примечание: у меня нет образования психолога. Статья основана только на моём личном опыте, а выводы сделаны на основе сотен страниц психологической литературы, десятков часов карьерных курсов и консультаций, и сотен часов без сна в думах о...
Написать сообщение
Тип
Почта
Имя
*Сообщение
RSS
Если вам понравился этот сайт и вы хотите меня поддержать, вы можете
Soft skills: 18 самых важных навыков, которыми должен владеть каждый работник
Мультитаскинг, или Как работать над несколькими проектами и не сойти с ума
Using a сustom PagedList class for Generic Pagination in .NET Core
Как мы столкнулись с версионированием и осознали, что вариант «просто проставить цифры» не работает
9 главных трендов в разработке фронтенда в 2024 году
Рассуждение на тему, какую базу данных выбирать
Бредовая работа
Доводим разработчика до выгорания: три простых шага
Вопросы с собеседований, которые означают не то, что вы думаете
Семь итераций наивности или как я полтора года свою дебютную игру писал
LinkedIn: Sergey Drozdov
Boosty
Donate to support the project
GitHub account
GitHub profile