Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: Optimize performance of LocalizationProvider.Translate<T> method #342

Merged
merged 1 commit into from
Nov 27, 2024

Conversation

hangy
Copy link
Contributor

@hangy hangy commented Nov 23, 2024

  1. Use jsonToken.ToObject<T> instead of jsonToken.ToString() to deserialize the JToken
  2. Cache JsonSerializer for repeated use

Contributes to #341

Benchmarks
using BenchmarkDotNet.Attributes;
using DbLocalizationProvider.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace DbLocalizationProvider.Benchmarks;

[MemoryDiagnoser]
public class LocalizationProviderBenchmark
{
    private static readonly StaticPropertyContractResolver s_resolver = new();

    private static readonly JsonSerializer s_serializer = new()
    {
        ContractResolver = s_resolver
    };

    private const string json = """
    {
        "PropertyInAllLanguages": "FR",
        "PropertyOnlyInEnglish": "EN",
        "PropertyOnlyInInvariant": "INVARIANT"
      }
""";

    private readonly JToken s_jsonToken = JToken.Parse(json);

    [Benchmark]
    public SomeResourceClass Original()
    {
        return JsonConvert.DeserializeObject<SomeResourceClass>(s_jsonToken.ToString(),
                                                new JsonSerializerSettings
                                                {
                                                    ContractResolver = new StaticPropertyContractResolver()
                                                });
    }

    private static readonly JsonSerializerSettings s_jsonSerializerSettings = new()
    {
        ContractResolver = new StaticPropertyContractResolver()
    };

    [Benchmark]
    public SomeResourceClass OriginalStaticSettings()
    {
        return JsonConvert.DeserializeObject<SomeResourceClass>(s_jsonToken.ToString(), s_jsonSerializerSettings);
    }

    [Benchmark]
    public SomeResourceClass JTokenDirect()
    {
        return s_jsonToken.ToObject<SomeResourceClass>(new JsonSerializer
        {
            ContractResolver = new StaticPropertyContractResolver()
        });
    }

    [Benchmark]
    public SomeResourceClass JTokenDirectStaticResolver()
    {
        return s_jsonToken.ToObject<SomeResourceClass>(new JsonSerializer
        {
            ContractResolver = s_resolver
        });
    }

    [Benchmark]
    public SomeResourceClass JTokenDirectStaticSerializer()
    {
        return s_jsonToken.ToObject<SomeResourceClass>(s_serializer);
    }

    public class SomeResourceClass
    {
        public string PropertyInAllLanguages { get; set; } = "In all languages";
        public string PropertyOnlyInEnglish { get; set; } = "Only in English";
        public string PropertyOnlyInInvariant { get; set; } = "Only in Invariant";
        public string PropertyInFrenchAndEnglish { get; set; } = "Only in Invariant";
    }

}
BenchmarkDotNet v0.14.0, Windows 11 (10.0.22621.4460/22H2/2022Update/SunValley2)
AMD Ryzen 7 7800X3D, 1 CPU, 16 logical and 8 physical cores
.NET SDK 9.0.100
  [Host]     : .NET 9.0.0 (9.0.24.52809), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI
  DefaultJob : .NET 9.0.0 (9.0.24.52809), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI


| Method                       | Mean         | Error       | StdDev      | Gen0   | Allocated |
|----------------------------- |-------------:|------------:|------------:|-------:|----------:|
| Original                     | 279,186.8 ns | 1,849.91 ns | 1,730.40 ns | 0.4883 |   41022 B |
| OriginalStaticSettings       |     716.5 ns |     9.60 ns |     8.51 ns | 0.0792 |    4008 B |
| JTokenDirect                 | 270,274.6 ns | 1,806.91 ns | 1,601.77 ns | 0.4883 |   37196 B |
| JTokenDirectStaticResolver   |     238.4 ns |     0.88 ns |     0.73 ns | 0.0091 |     472 B |
| JTokenDirectStaticSerializer |     230.0 ns |     0.78 ns |     0.65 ns | 0.0048 |     248 B |

@valdisiljuconoks valdisiljuconoks self-requested a review November 27, 2024 20:06
@valdisiljuconoks valdisiljuconoks self-assigned this Nov 27, 2024
@valdisiljuconoks valdisiljuconoks added this to the 8.2.3 milestone Nov 27, 2024
@valdisiljuconoks valdisiljuconoks merged commit 6934156 into valdisiljuconoks:master Nov 27, 2024
2 checks passed
@hangy hangy deleted the issue341 branch November 27, 2024 22:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants