Skip to content

Fix XmlSerializer UnknownAttribute perf regression - #131908

Open
StephenMolloy wants to merge 2 commits into
dotnet:mainfrom
StephenMolloy:131813-XmlSerialzier_UnknownAttribute_Perf_Regression
Open

Fix XmlSerializer UnknownAttribute perf regression#131908
StephenMolloy wants to merge 2 commits into
dotnet:mainfrom
StephenMolloy:131813-XmlSerialzier_UnknownAttribute_Perf_Regression

Conversation

@StephenMolloy

@StephenMolloy StephenMolloy commented Aug 5, 2026

Copy link
Copy Markdown
Member

This change avoids attribute enumeration when an element has no attributes across all serializer implementations. The reflection-based serializer additionally avoids enumeration when no UnknownNode or UnknownAttribute handlers are registered. Generated C# and RefEmit readers cannot inspect subscriber state without adding protected API surface to XmlSerializationReader, so they retain attribute enumeration when attributes are present. That additional optimization is intentionally out of scope.

Attribute Handling Logic Updates:

  • Refactored HandleUnknownAttributes in ReflectionXmlSerializationReader and 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 marked xsi:nil. [1] [2] [3] [4] [5]
  • Updated code generation in both C# and IL (XmlSerializationReader.cs and XmlSerializationReaderILGen.cs) to match the new logic, ensuring consistency between runtime and generated serializers. [1] [2] [3] [4] [5] [6] [7] [8]

Behavioral Consistency:

  • Ensured that elements marked as xsi:nil do 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

… 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.
@StephenMolloy StephenMolloy added this to the 11.0.0 milestone Aug 5, 2026
@StephenMolloy StephenMolloy self-assigned this Aug 5, 2026
Copilot AI review requested due to automatic review settings August 5, 2026 22:13
@azure-pipelines

Copy link
Copy Markdown
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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 MoveToNextAttribute when Reader.HasAttributes is false, and to ensure nil-handling paths don’t surface attributes.
  • Added tests and a tracking XmlReader wrapper 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.

Comment thread src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs Outdated
Comment thread src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs Outdated
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
Copilot AI review requested due to automatic review settings August 6, 2026 19:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

@StephenMolloy
StephenMolloy marked this pull request as ready for review August 6, 2026 21:25
@StephenMolloy
StephenMolloy requested a review from mangod9 August 6, 2026 21:26
@azure-pipelines

Copy link
Copy Markdown
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Perf] Windows/x64: 5 Regressions on 7/30/2026 6:50:50 PM +00:00

2 participants