Fix XmlSerializer UnknownAttribute perf regression - #131908
Fix XmlSerializer UnknownAttribute perf regression#131908StephenMolloy wants to merge 2 commits into
Conversation
… performance - Removed redundant calls to HandleUnknownAttributes in ReflectionXmlSerializationReader. - Consolidated attribute handling logic to avoid unnecessary attribute enumeration for built-in typed members. - Introduced AttributeTrackingXmlReader to track attribute operations during deserialization. - Added unit tests to verify that attributes are not enumerated when not needed and to ensure correct behavior with stray attributes.
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Pull request overview
This PR adjusts XmlSerializer deserialization for primitive/array/collection-mapped elements to reduce unnecessary attribute walking and to align unknown-attribute surfacing behavior more closely with other mapping paths. It also extends the test suite to validate attribute enumeration behavior (including xsi:nil handling) using a tracking XmlReader.
Changes:
- Updated reflection-based deserialization to skip unknown-attribute enumeration unless there are unknown-node/attribute subscribers and the element actually has attributes.
- Updated generated-reader code emission (C# + IL) to avoid
MoveToNextAttributewhenReader.HasAttributesis false, and to ensure nil-handling paths don’t surface attributes. - Added tests and a tracking
XmlReaderwrapper to assert attribute enumeration / lookup behavior.
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs | Adds attribute-enumeration tracking tests and an XmlReader wrapper to validate the new behavior. |
| src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReaderILGen.cs | Adjusts emitted IL to gate attribute enumeration behind Reader.HasAttributes and reorders calls around ReadNull. |
| src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs | Adds an internal “has subscribers” helper and updates generated-source emission to check Reader.HasAttributes before enumerating. |
| src/libraries/System.Private.Xml/src/System/Xml/Serialization/ReflectionXmlSerializationReader.cs | Refactors unknown-attribute handling to return early when there are no relevant event subscribers and/or no attributes. |
Keep the tests focused on observable unknown-attribute behavior rather than implementation-specific attribute enumeration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b9c6a54b-bbea-4359-b26b-4117f7a51d88
There was a problem hiding this comment.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.
Note
This error may be related to your runner configuration. You can now configure runners for Copilot code review separately from Copilot cloud agent by creating a copilot-code-review.yml file with your setup steps. Read the docs for details.
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
This change avoids attribute enumeration when an element has no attributes across all serializer implementations. The reflection-based serializer additionally avoids enumeration when no
UnknownNodeorUnknownAttributehandlers are registered. Generated C# and RefEmit readers cannot inspect subscriber state without adding protected API surface toXmlSerializationReader, so they retain attribute enumeration when attributes are present. That additional optimization is intentionally out of scope.Attribute Handling Logic Updates:
HandleUnknownAttributesinReflectionXmlSerializationReaderand related codegen to only enumerate attributes if there are subscribers to unknown node or attribute events and the element has attributes, instead of always enumerating unless the element is markedxsi:nil. [1] [2] [3] [4] [5]XmlSerializationReader.csandXmlSerializationReaderILGen.cs) to match the new logic, ensuring consistency between runtime and generated serializers. [1] [2] [3] [4] [5] [6] [7] [8]Behavioral Consistency:
xsi:nildo not surface their attributes as unknown, maintaining consistency with struct deserialization. [1] [2] [3] [4]These changes improve performance and correctness by reducing unnecessary attribute enumeration and aligning the handling of unknown attributes across different mapping types.
Fixes #131813