Skip to content

Reduce number of runtime assemblies that a typical app has to load #2138

Open

Description

@jkotas

For histroric reasons, .NET Core runtime has many small facades and partial facades that do not serve any meaninful purpose anymore. We should consider merging some of them to reduce number of assemlies that a typical app has to load. Unfortunately, we cannot delete them because of backward compatibility.

Example of merged facade looks like: System.AppContext. Notice that ref has type-forwards only and src has no implementation files.

List of proposed merges:

  • Merge into System.Private.CoreLib\src:

    • System.Threading.Thread\src
    • System.Diagnosics.Tools\src
    • System.Security.Principal\src
    • System.Runtime\src
    • System.Runtime.Extensions\src
  • Merge into System.Runtime\ref:

    • System.Buffers\ref
    • System.Diagnosics.Debug\ref
    • System.Resources.ResourceManager\ref
    • System.Runtime.Loader\ref
    • System.Text.Encoding.Extensions\ref
    • System.Threading.Tasks\ref
    • System.Threading.ThreadPool\ref
    • System.Threading.Timer\ref
    • System.Threading.Thread\ref
    • System.Diagnosics.Tools\ref
    • System.Security.Principal\ref
    • System.Runtime.Extensions\ref
  • Misc other cleanup

    • Stop building packages for System.Reflection.Emit.*
    • Stop building packages for System.Reflection.TypeExtensions
    • Simplify build configurations for implementations that just foward to other contracts (e.g. System.AppContext\src can have just a single configuration)
    • Delete System.Reflection.Emit.*\src\Resources\Strings.resx
    • Delete System.Buffers\src\Resources\Strings.resx
    • Delete System.Threading.Timer\src\ApiCompatBaseline.uapaot.txt
    • Merge System.Reflection.Emit.\ref\System.Reflection.Emit..netcore.cs into System.Reflection.Emit\ref\System.Reflection.Emit.*.cs
    • Delete System.IO.UnmanagedMemoryStream\ref\System.IO.UnmanagedMemoryStream.cs
    • Delete System.Reflection\ref\System.Reflection.cs
  • Wave 2: It is less obvious that the merging is a good idea for these (big enough, platform specific, etc.) We may still do some merging for them, based on the experience from the Wave 1 above:

    • System.Diagnostics.Contracts
    • System.Diagnostics.Tracing
    • System.Numerics.Vectors
    • System.Reflection.Emit
    • System.Reflection.Primitives
    • System.Threading.Overlapped
    • System.Memory
    • System.Reflection.TypeExtensions
    • System.Threading
    • System.Collections
    • System.Collections.Concurrent

Activity

  1. jkotas commented on Jan 24, 2020

    @jkotas
    MemberAuthor
  2. removed
    untriagedNew issue has not been triaged by the area owner
    on Jan 24, 2020
  3. added this to the 5.0 milestone on Jan 24, 2020
  4. danmoseley commented on Jan 25, 2020

    @danmoseley
    Contributor

    @ericstj thoughts about merging System.Collections? @eanova was about to work on a change to HashSet that woudl benefit from it being inside corelib. If we want to merge it, he can do it. If we don't, we could just move HashSet.

  5. Symbai commented on Jan 27, 2020

    @Symbai

    Wouldn't this cause a potential conflict with PublishTrimmed=true by making the output size even bigger? Or is the linker now smart enough to eliminate unused code in assemblies?

  6. jkotas commented on Jan 27, 2020

    @jkotas
    MemberAuthor

    PublishTrimmed=true by making the output size even bigger?

    I expect that it will be a noise at the end. It will reduce number of tiny files that survive and make the few files bigger. Note that most of the tiny facades that this is about are used by every reasonable app, so the chances that the linker was able to remove them are pretty low.

    The default for PublishTrimmed=true is assembly level trimming currently. This leaves a lot of unused code on the table. The linker was always smart enough to do method level trimming, but there is work needed in libraries to give linker information about the methods accessed by reflection so that the app still works after method-level trimming.

  7. ericstj commented on Jan 27, 2020

    @ericstj
    Member

    System.Collections is actually somewhat large: 324 KB. @jkotas you had this in wave 2 originally. Are you concerned about growth of working set? I see that the console template doesn't normally use System.Collections, but MVC does. I didn't check all the templates. I tend to agree that most apps probably use this. I wonder if we could get data on this to back up that claim. 🤔

    An alternative, more piecemeal solution here would be to push down all types that are implemented in S.P.C to System.Runtime. Then change these partial facades into plain assemblies referencing System.Runtime. We could then decide case-by-case about moving types down based on tradeoffs to size vs usage.

  8. jkotas commented on Jan 27, 2020

    @jkotas
    MemberAuthor

    System.Collections is actually somewhat large: 324 KB

    Compare this to S.P.CoreLib size that is 10MB. The profile-guided layout for S.P.CoreLib is a must-have to split these 10MB into what is actually used and get a decent working set. These extra 300kB from System.Collections would just get for a free ride.

  9. danmoseley commented on Aug 7, 2020

    @danmoseley
    Contributor

    @jkotas I assume no more work is planned here for 5.0. Moving to Future

  10. removed this from the 5.0.0 milestone on Aug 7, 2020
  11. 1 remaining item

  12. dotnet-policy-service commented on Feb 7, 2025

    @dotnet-policy-service
    Contributor

    Due to lack of recent activity, this issue has been marked as a candidate for backlog cleanup. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will undo this process.

    This process is part of our issue cleanup automation.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions