graphql-platform icon indicating copy to clipboard operation
graphql-platform copied to clipboard

Poor startup performance due to XML comment inference

Open N-Olbert opened this issue 3 months ago • 2 comments

Product

Hot Chocolate

Version

15.1.10

Link to minimal reproduction

Steps to reproduce

We have a huge schema (~8k fields, 30k lines with comments, 12k lines without)

Nearly every field is documented in detail and we also have lots of <see cref=""/> within the docs.

Currently, the startup of the service takes about 25 seconds.

A quick profiling showed that a significant amount of time is spent on infering the xml documentation from the code within the XmlDocumentationProvider

Image

Within this method, navigating through the document by XPath takes most of the time.

When disabling the XML doc inference (.ModifyOptions(static x => x.UseXmlDocumentation = !Debugger.IsAttached)), the start-up time is reduced drastically (~14 seconds).

What is expected?

Not a too big perf impact of XML comment inference (and maybe the feature should be disabled by default for dev environments).

What is actually happening?

Slow startup

Relevant log output


Additional context

I wonder whether it could be beneficial to use XPathDocument instead of XmlDocument there as the XPath navigation seems to be the bottleneck.

N-Olbert avatar Oct 07 '25 12:10 N-Olbert

8k fields is not a large schema :)

The XML documentation did not get a lot of love the last couple of years. Basically we kept it as is, since it was contributed.

I think the best way forward on this for us would be to move the thing into the source generator. It makes not really sense to do this kind of work on every startup. But also if we make that part of the source generator we need to make it more efficient as we do not want to drag build perf down the drain.

I am putting this on the backlog for V16

michaelstaib avatar Oct 08 '25 15:10 michaelstaib

I think the best way forward on this for us would be to move the thing into the source generator.

Yes, this seems to be the best way 👍

Anyway, the current implementation will probably have to be kept, since there’s still the possibility of registering types dynamically at runtime. I took a quick look at the current implementation and think there’s some potential to optimize it, even without overthinking it too much. I`ll spend some time on investigating this further.

N-Olbert avatar Oct 08 '25 21:10 N-Olbert