question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Perf bottleneck because of SortedDictionary in Annotatable.FindAnnotation

See original GitHub issue

The following was reported offline by @feng-yuan (thanks!)

Found an expensive EF stack:

stacktrace

GetValueComparer is costing 139 k CPU samples, 6% in this hot stream, mostly due to SortedDictionary lookup in Annotable.FindAnnotation.

We know sorted dictionary is slower than dictionary because its lookup is O(Ln(N)), but there is something more to make the code slower, or even incorrect here.

protected virtual Annotation SetAnnotation([NotNull] string name, [NotNull] Annotation annotation, [CanBeNull] Annotation oldAnnotation)
{
    if (this._annotations == null)
    {
        this._annotations = new SortedDictionary<string, Annotation>();
    }
    this._annotations[name] = annotation;
    return this.OnAnnotationSet(name, annotation, oldAnnotation);
}

SortedDictionary<string, Annotation> is allocated with default constructor. So the comparer is using String.Compare which is using current culture. Here is the evidence:

stacktrace2

String.CompareTo is on the right. Zoom-in:

stacktrace3

So lookup is now dependent on current thread culture.

At least, you need to change the code to :

if (this._annotations == null)
{
    this._annotations = new SortedDictionary<string, Annotation>(StringComparer.Ordinal);
}

If order is not important, Dictionary<string, Annotation> would be even faster and smaller.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:1
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
AndriySvyrydcommented, Oct 3, 2021

Since GetAnnotations isn’t used frequently we could sort on demand and use Hashtable/Dictionary<string, Annotation>

1reaction
AndriySvyrydcommented, Aug 13, 2021

In 6.0.0 we introduced the optimized runtime model and RuntimeProperty.GetValueComparer() doesn’t look for an annotation, as it’s now stored in a field. So this bottleneck should be gone.

Read more comments on GitHub >

github_iconTop Results From Across the Web

No results found

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found