Unleash / unleash-client-dotnet

Unleash client SDK for .NET
Apache License 2.0
77 stars 39 forks source link

Don't Clone Context in UnleashContext.ApplyStaticFields #193

Closed nathanmascitelli closed 7 months ago

nathanmascitelli commented 7 months ago

Description

When calling IUnleash.IsEnabled we end up cloning the UnleashContext. This cloning is not needed and expensive since the entire Properties dictionary needs to be cloned. This case removes the cloning.

Fixes #186

Type of change

Please delete options that are not relevant.

How Has This Been Tested?

Using the following benchmark (note IsEnabled2 calls the code proposed in this PR):

[MemoryDiagnoser]
public class Benchmark
{
    readonly UnleashContext context = new();
    readonly DefaultUnleash client = new(new UnleashSettings());

    public Benchmark()
    {
        // Remove this loop to test empty properties
        for (int i = 0; i < 10; i++)
        {
            context.Properties.Add(i.ToString(), i.ToString());
        }
    }

    [Benchmark(Baseline = true)]
    public bool Current() => client.IsEnabled("Moo", context);

    [Benchmark]
    public bool NoClone() => client.IsEnabled2("Moo", context);
}

The following results were obtained:

Empty Properties

Method Mean Error StdDev Ratio Gen0 Allocated Alloc Ratio
Current 179.3 ns 1.80 ns 1.69 ns 1.00 0.0408 512 B 1.00
NoClone 145.8 ns 1.06 ns 0.94 ns 0.81 0.0274 344 B 0.67

10 Elements in Properties

Method Mean Error StdDev Ratio Gen0 Allocated Alloc Ratio
Current 262.7 ns 2.64 ns 2.34 ns 1.00 0.0691 872 B 1.00
NoClone 144.8 ns 2.65 ns 3.45 ns 0.56 0.0274 344 B 0.39