Skip to content

[RuntimeAsync] NativeAOT code size #125148

@agocke

Description

@agocke

We expect that runtime-async should save in code size for heavy async methods. There's some evidence this is true, but we should see if we can make even more improvements.

Looking just at the libraries tests that are currently compiled with runtime-async and Native AOT, we see the ones with the most async code shrunk the most:

  • System.Net.Http.Functional.Tests: -3.6MB (-9.9%)
  • System.Linq.AsyncEnumerable.Tests: -1.1MB (-5.4%)
  • System.Net.Quic.Functional.Tests: -473K
  • System.IO.Pipelines.Tests: -472K
  • System.Threading.RateLimiting.Tests: -372K

However we also saw that for places that have very few or no async methods, size may very slightly increase (0.4%). For example,

System.Console.Tests (+43K) and System.Text.Encoding.Tests (+80K) show growth from:

  • New AsyncCallable wrappers for test methods (e.g., ReadAndWrite.OutWriteAndWriteLineOverloads — 4KB new wrapper)
  • New RuntimeAsyncTask helpers from CoreLib (~1.2KB each, multiple generic instantiations)
  • New ValueTaskAwaiter/ConfiguredValueTaskAwaitable methods — new async infrastructure code
  • Growth in __InterfaceDispatchCellSection, _stacktrace_methodRVA_to_token_mapping, __dehydrated_data to
    accommodate the new methods

The old state machine MoveNext methods are removed (e.g., -4045 bytes for
OutWriteAndWriteLineOverloads_d__7.MoveNext) but the new AsyncCallable wrappers + RuntimeAsyncTask infrastructure
exceed the savings for tests with only a few async methods. The async transformation only pays off in binaries with
many async methods sharing generic instantiations (like System.Linq.AsyncEnumerable.Tests).

Metadata

Metadata

Assignees

Type

No type

Projects

Status

No status

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions