Skip to content

Enable UseSizeOptimizedLinq by default on native AOT #113214

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 12, 2025

Conversation

MichalStrehovsky
Copy link
Member

The motivation is:

  • This has been enabled by default on mobile platforms for several releases and it wasn't a source of issues there
  • It is easy to opt out of it. (That cannot be said about mobile platforms in the past that hardcoded it at repo build).
  • Doesn't have measurable throughput impact on any ASP.NET scenarios we measure perf of.
  • It is a meaningful size saving (seen 5+%).

Cc @dotnet/ilc-contrib

The motivation is:

* This has been enabled by default on mobile platforms for several releases and it wasn't a source of issues
* It is easy to opt out of it. (That cannot be said about mobile platforms in the past that hardcoded it at repo build).
* Doesn't have measurable throughput impact on any ASP.NET scenarios we measure perf of.
* It is a meaningful size saving (seen 5+%).
@Copilot Copilot AI review requested due to automatic review settings March 6, 2025 12:34
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 1 out of 1 changed files in this pull request and generated no comments.

@MichalStrehovsky
Copy link
Member Author

/azp run runtime-nativeaot-outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Contributor

Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas
See info in area-owners.md if you want to be subscribed.

@EgorBo
Copy link
Member

EgorBo commented Mar 6, 2025

Doesn't have measurable throughput impact on any ASP.NET scenarios we measure perf of.

I assume none of them have LINQ in the hot path, at least the ones NativeAOT supports

@am11
Copy link
Member

am11 commented Mar 6, 2025

Does it need a breaking change tag per #109978 (comment)?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;

MyList<int> list = new([1, 2, 3, 4, 5, 6]);
foreach (var item in list.Skip(3).Take(2).Select(item => item)) Console.WriteLine(item);

public class MyList<T>(IList<T> innerList) : IList<T> where T : IMultiplyOperators<T, int, T>
{
    public T this[int index]
    {
        get => innerList[index] * 2;
        set => innerList[index] = value;
    }

    public int Count => innerList.Count;
    public bool IsReadOnly => innerList.IsReadOnly;
    public void Add(T item) => innerList.Add(item);
    public void Clear() => innerList.Clear();
    public bool Contains(T item) => innerList.Contains(item);
    public void CopyTo(T[] array, int arrayIndex) => innerList.CopyTo(array, arrayIndex);
    public int IndexOf(T item) => innerList.IndexOf(item);
    public void Insert(int index, T item) => innerList.Insert(index, item);
    public bool Remove(T item) => innerList.Remove(item);
    public void RemoveAt(int index) => innerList.RemoveAt(index);
    public IEnumerator<T> GetEnumerator() => innerList.GetEnumerator();
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
}

main:

8
10

PR:

4
5

@MichalStrehovsky
Copy link
Member Author

Does it need a breaking change tag per #109978 (comment)?

Hm, do we do a breaking change announcement every time we optimize something in LINQ? (The PR behavior is the same behavior as on .NET Framework.)

@jkotas
Copy link
Member

jkotas commented Mar 6, 2025

Does it need a breaking change tag per #109978 (comment)?

I do not think so. Linq expects correct implementation of collection contracts. If the collection contracts are not implemented correctly, all bets are off with Linq.

@jkotas
Copy link
Member

jkotas commented Mar 9, 2025

Are the failures related to the PR?

@MichalStrehovsky
Copy link
Member Author

Are the failures related to the PR?

No, it's the AppContext.BaseDirectory change that broke all Linux. I'll update the branch and rerun testing. But Windows was green.

@MichalStrehovsky
Copy link
Member Author

/azp run runtime-nativeaot-outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MichalStrehovsky MichalStrehovsky merged commit 6cfbc7d into dotnet:main Mar 12, 2025
113 of 115 checks passed
@MichalStrehovsky MichalStrehovsky deleted the linq branch March 12, 2025 13:35
@github-actions github-actions bot locked and limited conversation to collaborators Apr 12, 2025
@ericstj ericstj added breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet labels Apr 25, 2025
@ericstj
Copy link
Member

ericstj commented Apr 25, 2025

@MichalStrehovsky can you please create a breaking change document for this change to help those impacted understand the reasoning for the change and what action they should take if impacted?

@ericstj
Copy link
Member

ericstj commented Apr 25, 2025

Also given how users are noticing this change - it might be better to consider not enabling by default but somehow advertising it's presence for those that care about size and are willing to do work to refactor their code if it causes issues.

@jkotas
Copy link
Member

jkotas commented Apr 25, 2025

@ericstj We have discussed whether or not this should be tracked as a breaking change above and the conclusion was that is not needed:
#113214 (comment)
#113214 (comment)

Could you please share you reasoning why it is needed and what would the breaking change say?

The "break" is that if a user has invalid implementation of collection contracts, they can see behavior changes. We have done number of similar "breaks" outside of NativeAOT in the past without filling breaking change notices.

@richlander
Copy link
Member

I think the breaking change aspect is a red herring. It might be more useful to update some design or learn doc to explain that our optimizations will favor size over startup/throughput and that we have a knob for adjusting that. I suspect that the community reaction is more one of surprise. If we don't have our intentions clearly written down in a place they know to look, then that's understandable.

@tannergooding
Copy link
Member

A callout in the .NET 10 release notes would at least seem reasonable, even if not documented as breaking. Just so we have a centralized place to refer to.

There is an issue (115033) opened last night that is negatively impacted be the change and which is currently getting a lot of passionate community discussion.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-NativeAOT-coreclr breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants