Skip to content

XmlSerializer: route formatted primitive output through span-based raw writer fast path#128505

Draft
Copilot wants to merge 3 commits into
mainfrom
copilot/optimize-xml-serialization-primitives
Draft

XmlSerializer: route formatted primitive output through span-based raw writer fast path#128505
Copilot wants to merge 3 commits into
mainfrom
copilot/optimize-xml-serialization-primitives

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 22, 2026

This change targets the primitive-write hot path in XmlSerializationWriter, where formatted values (notably decimal) were still funneled through WriteRaw(char[], ...) and could incur avoidable conversions in the underlying writer stack. It adds an internal span-based raw-write path so default raw text writers can consume formatted primitive data directly.

  • Serializer hot-path update

    • WriteTypedPrimitive now uses a span path when the writer is XmlWellFormedWriter, passing _primitivesBuffer.AsSpan(0, charsWritten) into an internal raw-write overload.
    • Existing char[] fallback remains for non-XmlWellFormedWriter cases.
  • Raw writer pipeline extension

    • Added internal virtual WriteRaw(ReadOnlySpan<char>) to XmlRawWriter (default fallback to existing string-based behavior).
    • Added internal WriteRaw(ReadOnlySpan<char>) in XmlWellFormedWriter to preserve state machine behavior and forward to underlying raw writers.
  • Fast-path implementations

    • XmlUtf8RawTextWriter and XmlEncodedRawTextWriter now override span-based raw writing and feed spans directly into existing raw char-checking/output routines.
    • Matching updates were made in XmlRawTextWriterGenerator.ttinclude and the generated writer sources.
    • Indent writer variants were also updated so span raw writes still set mixed-content state correctly.
  • Coverage update

    • Added Xml_DecimalArrayAsRoot to XmlSerializerTests.RuntimeOnly.cs to exercise primitive-array serialization/round-trip on this path.
// XmlSerializationWriter.WriteTypedPrimitive
if (_w is XmlWellFormedWriter wellFormedWriter)
{
    wellFormedWriter.WriteRaw(_primitivesBuffer.AsSpan(0, charsWritten));
}
else
{
    _w.WriteRaw(_primitivesBuffer, 0, charsWritten);
}

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • bla
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26257.113/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing e/.dotnet/bash urity.Cryptograp/home/REDACTED/work/runtime/runtime/.dotnet/dotnet /lib/x86_64-linu/home/REDACTED/work/runtime/runtime/artifacts/bin/ILLink.Tasks/Debug/net/illink.dll /usr/bin/../lib/@/tmp/MSBuildTempZLMhIi/tmp0ef4b4df5791499bb66cd3620b8aacff.rsp PORTS (dns block)
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26257.113/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing e/.dotnet/sdk/11.0.100-preview.5.26227.104/MSBuild ORT_SHARED_API -git OS -DHOST_AMD64 e/.dotnet/sdk/11HEAD (dns block)
  • foo
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26257.113/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing e/.dotnet/bash urity.Cryptograp/home/REDACTED/work/runtime/runtime/.dotnet/dotnet /lib/x86_64-linu/home/REDACTED/work/runtime/runtime/artifacts/bin/ILLink.Tasks/Debug/net/illink.dll /usr/bin/../lib/@/tmp/MSBuildTempZLMhIi/tmp0ef4b4df5791499bb66cd3620b8aacff.rsp PORTS (dns block)
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26257.113/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing e/.dotnet/sdk/11.0.100-preview.5.26227.104/MSBuild ORT_SHARED_API -git OS -DHOST_AMD64 e/.dotnet/sdk/11HEAD (dns block)
  • notfound.invalid.corp.microsoft.com
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26257.113/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing e/.dotnet/bash urity.Cryptograp/home/REDACTED/work/runtime/runtime/.dotnet/dotnet /lib/x86_64-linu/home/REDACTED/work/runtime/runtime/artifacts/bin/ILLink.Tasks/Debug/net/illink.dll /usr/bin/../lib/@/tmp/MSBuildTempZLMhIi/tmp0ef4b4df5791499bb66cd3620b8aacff.rsp PORTS (dns block)
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26257.113/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing e/.dotnet/sdk/11.0.100-preview.5.26227.104/MSBuild ORT_SHARED_API -git OS -DHOST_AMD64 e/.dotnet/sdk/11HEAD (dns block)
  • test.test
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26257.113/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing e/.dotnet/bash urity.Cryptograp/home/REDACTED/work/runtime/runtime/.dotnet/dotnet /lib/x86_64-linu/home/REDACTED/work/runtime/runtime/artifacts/bin/ILLink.Tasks/Debug/net/illink.dll /usr/bin/../lib/@/tmp/MSBuildTempZLMhIi/tmp0ef4b4df5791499bb66cd3620b8aacff.rsp PORTS (dns block)
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26257.113/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing e/.dotnet/sdk/11.0.100-preview.5.26227.104/MSBuild ORT_SHARED_API -git OS -DHOST_AMD64 e/.dotnet/sdk/11HEAD (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

…r path

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/29c71057-04f8-4c4e-9c5f-5442fe10a352

Co-authored-by: StephenMolloy <19562826+StephenMolloy@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot May 22, 2026 23:09
…w writer fast path

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/29c71057-04f8-4c4e-9c5f-5442fe10a352

Co-authored-by: StephenMolloy <19562826+StephenMolloy@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot May 22, 2026 23:30
Copilot AI changed the title [WIP] Optimize Xml serialization for primitive objects XmlSerializer: route formatted primitive output through span-based raw writer fast path May 22, 2026
Copilot AI requested a review from StephenMolloy May 22, 2026 23:31
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.

[Xml Serialization] Possible optimization when writing primitive objects

2 participants