Skip to content

[XmlSerializer] Avoid IList/Array.GetValue path for array item serialization in reflection writer#128504

Draft
Copilot wants to merge 2 commits into
mainfrom
copilot/optimize-reflection-xml-serialization
Draft

[XmlSerializer] Avoid IList/Array.GetValue path for array item serialization in reflection writer#128504
Copilot wants to merge 2 commits into
mainfrom
copilot/optimize-reflection-xml-serialization

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 22, 2026

XmlSerializer’s reflection path was serializing arrays through IList, which can devolve to Array.GetValue per element and add avoidable overhead in tight loops. This change introduces an explicit array path in ReflectionXmlSerializationWriter.WriteArrayItems to keep array iteration on the direct array/enumerator path.

  • Problem

    • WriteArrayItems treated arrays as IList, so element access used arr[i] and could hit slower Array.GetValue behavior for primary-type arrays.
  • Change

    • Added an early if (o is Array array) branch in ReflectionXmlSerializationWriter.WriteArrayItems.
    • Iterates array items directly and forwards each item to WriteElements.
    • Hoisted choiceSources cast to a single Array? choiceArray and reused it across array/list/enumerable paths.
  • Behavioral scope

    • Serialization output semantics are unchanged.
    • Change is localized to iteration strategy in the reflection serializer array-item loop.
Array? choiceArray = choiceSources as Array;

if (o is Array array)
{
    IEnumerator e = array.GetEnumerator();
    int c = 0;
    while (e.MoveNext())
    {
        object ai = e.Current;
        object? choiceSource = choiceArray?.GetValue(c++);
        WriteElements(ai, choiceSource, elements, text, choice, true, true);
    }

    return;
}

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 (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 urity.Cryptograp-DURTBLDENV_FRIENDLY=Debug c.c.o.d -o CMake/usr/bin/sh _ALIGNED SSUME_ALIGNED TARGET_UNIX -DUR-D_TIME_BITS=64 (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 k/_temp/ghcca-node/node/bin/bash -DFALLBACK_OS_Igit d/lib -DDEBUG Native_EXPORTS -DTARGET_64BIT -D/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-U0 (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 (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 urity.Cryptograp-DURTBLDENV_FRIENDLY=Debug c.c.o.d -o CMake/usr/bin/sh _ALIGNED SSUME_ALIGNED TARGET_UNIX -DUR-D_TIME_BITS=64 (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 k/_temp/ghcca-node/node/bin/bash -DFALLBACK_OS_Igit d/lib -DDEBUG Native_EXPORTS -DTARGET_64BIT -D/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-U0 (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 (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 urity.Cryptograp-DURTBLDENV_FRIENDLY=Debug c.c.o.d -o CMake/usr/bin/sh _ALIGNED SSUME_ALIGNED TARGET_UNIX -DUR-D_TIME_BITS=64 (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 k/_temp/ghcca-node/node/bin/bash -DFALLBACK_OS_Igit d/lib -DDEBUG Native_EXPORTS -DTARGET_64BIT -D/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-U0 (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 (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 urity.Cryptograp-DURTBLDENV_FRIENDLY=Debug c.c.o.d -o CMake/usr/bin/sh _ALIGNED SSUME_ALIGNED TARGET_UNIX -DUR-D_TIME_BITS=64 (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 k/_temp/ghcca-node/node/bin/bash -DFALLBACK_OS_Igit d/lib -DDEBUG Native_EXPORTS -DTARGET_64BIT -D/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-U0 (dns block)

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

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/bb7ee09b-36ff-43d7-9d23-45bdf352277f

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:14
Copilot AI changed the title [WIP] Optimize array serialization in ReflectionXmlSerializationWriter [XmlSerializer] Avoid IList/Array.GetValue path for array item serialization in reflection writer May 22, 2026
Copilot AI requested a review from StephenMolloy May 22, 2026 23:15
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]ReflectionXmlSerializationWriter is using Array.GetValue method for primary type arrays

2 participants