-
-
Notifications
You must be signed in to change notification settings - Fork 799
Improve performance of XML doc inference #8794
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
base: main
Are you sure you want to change the base?
Conversation
Worse for inheritdoc than before ChilliCream#8775
Full benchmark (values basically scale linearly)
|
.GetParameters() | ||
.Single(p => p.Name == "baz")); | ||
|
||
parameterXml = documentationProvider.GetDescription( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove
@@ -0,0 +1,1260 @@ | |||
using System.Collections.Concurrent; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="BenchmarkDotNet" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove
Summary of the changes (Less than 80 chars)
Related to #8775 (in this specific format)
As discussed in #8775, the current implementation was quite slow.
I intentionally did not introduce any big conceptual changes (yet) and focused only on optimizing the current implementation.
According to the benchmarks below, the general performance has improved by a factor between 2 and 22 (without the
inheritdoc
-cases, see below for them) - on average around 3.5× faster - while memory usage has been reduced significantly to around a third.For
inheritdoc
-cases, the situation is a bit different: I discovered that the current implementation mutates the XElement instances retrieved from the XmlDocumentationFileResolver, effectively modifying its internal cache.Here :
graphql-platform/src/HotChocolate/Core/src/Types/Types/Descriptors/Conventions/XmlDocumentationProvider.cs
Lines 320 to 321 in dfe075c
and here:
graphql-platform/src/HotChocolate/Core/src/Types/Types/Descriptors/Conventions/XmlDocumentationProvider.cs
Lines 353 to 354 in dfe075c
This behavior is both undesired (at least I think so) and not thread-safe.
To fix this, I changed the logic to create a copy of the XElement when resolving inheritdoc elements.
This ensures that the cache remains intact and that the implementation is thread-safe.
While this introduces a small performance regression for two out of six inheritdoc cases, I think it is justified since the previous implementation was incorrect and should not be considered a valid baseline: It only replaced the inheritdoc element once within the cached(!) XDocument, meaning that all subsequent calls for the same(!!!) member (which happens all the time in the benchmark) did not need to replace it again and threfore resulting in slightly better, but ultimately incomparable, performance characteristics. Of course, the current behavior could indeed be beneficial at runtime as well, f. e. an interface with many inheritors, but it is not that common as the benchmark indicates.
Overall, even for the
inheritdoc
-cases, the performance is still improved or comparable to before, and the memory usage is significantly lower:Note: The PR currently includes the benchmark code so that one can reproduce the results.
I would to remove these benchmarks after the review and applying any suggested change.
Note further: This is a breaking change since I reworked
XmlDocumentationFileResolver
to becomeXmlDocumentationResolver
.This change is not strictly neccessary, but IIRC it was a 10-20% speed boost - I will reevaluate the concret impact on request if the change seems unlikely to be acceptable.
Full benchmarks: