Skip to content

Conversation

github-actions[bot]
Copy link
Contributor

@github-actions github-actions bot commented Aug 18, 2025

Backport of #118156 to release/10.0-rc1

/cc @agocke

Customer Impact

  • Customer reported
  • Found internally

This is a bug fix for a LINQ regression in .NET 10 Native AOT caused by adopting the size-optimized version of some operators. This PR adjusts the size-optimized version of LINQ to have better computational complexity for a few operations, at the cost of (hopefully) small size increases.

We would ideally have this change in RC1 to ensure that these hypothesis are correct: that this addresses the most likely regression areas, and does not significantly increase the size.

Regression

  • Yes, from 9.0
  • No

Testing

Manual validation and unit tests.

Risk

Low. This PR mostly copies existing code from the mainline codepaths or removes special casing entirely, to use the standard coreclr code paths.

agocke and others added 15 commits August 18, 2025 04:48
This lets us keep some of the constant-time indexing advantages of the
IList iterator, without the GVM overhead of Select. There is a small
size increase here, but nowhere near the cost of the GVM.

In a pathological generated example for GVMs the cost was:

  1. .NET 9: 12 MB
  2. .NET 10 w/out this change: 2.2 MB
  3. .NET 10 w/ this change: 2.3 MB

In a real-world example (AzureMCP), the size attributed to System.Linq
was:

  1. .NET 9: 1.2 MB
  2. .NET 10 w/out this change: 340 KB
  3. .NET 10 w/ this change: 430 KB

This seems like a good tradeoff. We mostly keep the algorithmic
complexity the same across the size/speed-opt versions, and just
tradeoff on the margins. We could probably continue to improve this in
the future.
This takes a more aggressive direction and removes the size
optimized versions of iterators for Skip and Take. As far as
I can tell these are relatively small size increases, but
using them preserves the O(1) optimizations in the '
speed' version.
These are more (relatively common) cases where you could end up with an
O(n) implementation instead of O(1) even when the backing enumerable is
capable of doing O(1) index access.
@agocke agocke added the Servicing-consider Issue for next servicing release review label Aug 18, 2025
@teo-tsirpanis teo-tsirpanis added this to the 10.0.0 milestone Aug 18, 2025
Copy link
Member

@jeffschwMSFT jeffschwMSFT left a comment

Choose a reason for hiding this comment

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

lgtm. please get a code review. we will take for consideration in 10 rc1

@agocke
Copy link
Member

agocke commented Aug 18, 2025

@MichalStrehovsky mind reviewing the backport?

@artl93 artl93 self-requested a review August 18, 2025 21:40
@agocke agocke merged commit e2b61c7 into release/10.0-rc1 Aug 19, 2025
92 of 93 checks passed
@agocke agocke deleted the backport/pr-118156-to-release/10.0-rc1 branch August 19, 2025 15:57
@github-actions github-actions bot locked and limited conversation to collaborators Sep 19, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Servicing-approved Approved for servicing release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants