Skip to content

Conversation

@PranavSenthilnathan
Copy link
Member

@PranavSenthilnathan PranavSenthilnathan commented Oct 29, 2024

Fixes #107947 and #107944

Adds and consumes the following API:

namespace System.Collections.Generic;

public partial class OrderedDictionary<TKey, TValue>
{
    // Existing
    // public bool TryAdd(TKey key, TValue value);
    // public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value);
    public bool TryAdd(TKey key, TValue value, out int index);
    public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value, out int index);
}

Perf Impact:

Method Toolchain Count Mean Error StdDev Ratio RatioSD
AddAndUpdate main 1 126.1 ns 2.12 ns 1.77 ns 1.00 0.02
AddAndUpdate pr 1 112.7 ns 1.79 ns 1.68 ns 0.89 0.02
AddAndUpdate main 10 821.4 ns 11.77 ns 9.83 ns 1.00 0.02
AddAndUpdate pr 10 668.0 ns 13.07 ns 10.92 ns 0.81 0.02
AddAndUpdate main 50 3,886.8 ns 77.38 ns 163.21 ns 1.00 0.06
AddAndUpdate pr 50 3,014.6 ns 46.28 ns 41.02 ns 0.78 0.03
Expand for code
public class JsonObjectUpdate
{
    public string[] _keys = Array.Empty<string>();

    [Params(1, 10, 50)]
    public int Count;

    [GlobalSetup]
    public void Setup()
    {
        _keys = Enumerable.Range(1, Count).Select(i => $"prop{i}").ToArray();
    }

    [Benchmark]
    public JsonObject AddAndUpdate()
    {
        JsonObject obj = new JsonObject();

        foreach (var key in _keys)
        {
            obj[key] = default;
        }

        foreach (var key in _keys)
        {
            obj[key] = key;
        }

        return obj;
    }
}

@ghost
Copy link

ghost commented Oct 29, 2024

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

1 similar comment
@ghost
Copy link

ghost commented Oct 29, 2024

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@PranavSenthilnathan PranavSenthilnathan changed the title Add TryAdd and TryGetValue overloads with out var index to OrderedDictionary Add TryAdd and TryGetValue overloads with out int index to OrderedDictionary Oct 29, 2024
OrderedDictionary<string, JsonNode?> dict = Dictionary;

if (!dict.TryAdd(propertyName, value))
if (!dict.TryAdd(propertyName, value, out int index))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting the CI build error locally as well. I think the issue is that .net 9.0 doesn't have the new TryAdd(..., out int index) method (the failure indicates that the S.T.J. build for 9.0 is causing the error). Should I be ifdefing here to check for that?

Copy link
Member

@eiriktsarpalis eiriktsarpalis Oct 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ifdefing is fine. The alternative would be to polyfill the current version of OrderedDictionary for net9.0 as we do with the older targets, but I don't think this change is worth the duplication.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the style we use for #ifs but I wanted to avoid having the #if region cross into the if block.

Copy link
Member

@eiriktsarpalis eiriktsarpalis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, great work as usual!

@eiriktsarpalis
Copy link
Member

@PranavSenthilnathan should we get this merged?

@PranavSenthilnathan PranavSenthilnathan merged commit 251ef76 into dotnet:main Nov 1, 2024
83 checks passed
@PranavSenthilnathan
Copy link
Member Author

Added perf numbers to my first comment. Around 10-20% improvement for adding and updating in JsonObject (this PR improves the updating part of the scenario).

@eiriktsarpalis eiriktsarpalis added the tenet-performance Performance related issue label Nov 4, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Dec 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add an OrderedDictionary.TryAdd overload that returns the int-based index of an entry if the key already exists

3 participants