-
Notifications
You must be signed in to change notification settings - Fork 532
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
[Xamarin.Android.Build.Tasks] feature switch defaults for fast startup #8347
[Xamarin.Android.Build.Tasks] feature switch defaults for fast startup #8347
Conversation
Context: dotnet/runtime@fecf3ee Context: dotnet/runtime@3aeefbd Context: dotnet/runtime#89880 In dotnet/runtime two new feature switches were added in order to improve startup performance on Android: * `System.Diagnostics.Metrics.Meter.IsSupported`: disables `System.Diagnostics.Metrics` support for `HttpClient`, etc. * `Microsoft.Extensions.DependencyInjection.DisableDynamicEngine`: after the second call to retrieve a service from a dependency injection container, `System.Reflection.Emit is used to improve performance of repeated calls. We also have the existing switch: * `Switch.System.Reflection.ForceInterpretedInvoke`: after the second call to `MethodInfo.Invoke()` or `ConstructorInfo.Invoke()`, `System.Reflection.Emit is used to improve performance of repeated calls. Introduce two new MSBuild properties: * `$(AvoidEmitForPerformance)` to toggle both `Microsoft.Extensions.DependencyInjection.DisableDynamicEngine` and `Switch.System.Reflection.ForceInterpretedInvoke`. This is a public property that defaults to `true`, matching a property of the same name used somewhere in ASP.NET. * `$(_SystemDiagnosticsMetricsMeterIsSupported)` to toggle `System.Diagnostics.Metrics.Meter.IsSupported`. This is a private property that defaults to `false`. I added a test to check `System.Diagnostics.Metrics.Meter.IsSupported` at runtime. I did not do this with Microsoft.Extensions, as we'd have to add a reference to the NuGet package and track its version for nightly builds. I also updated the AOT profile, and some `System.Diagnostics.Metrics.Meter` API calls are gone now: bool System.Diagnostics.Metrics.Meter:AddInstrument (System.Diagnostics.Metrics.Instrument) object System.Diagnostics.Metrics.Instrument:get_SyncObject () System.Diagnostics.Metrics.Counter`1<long> System.Diagnostics.Metrics.Meter:CreateCounter (string,string,string,System.Collections.Generic.IEnumerable`1<System.Collections.Generic.KeyValuePair`2<string, object>>) System.Diagnostics.Metrics.Counter`1<long> System.Diagnostics.Metrics.Meter:CreateCounter (string,string,string) void System.Diagnostics.Metrics.MeterListener:.cctor () void System.Diagnostics.Metrics.MetricsEventSource:.cctor () void System.Diagnostics.Metrics.MetricsEventSource:.ctor ()
void System.Diagnostics.Metrics.MeterListener:.cctor () | ||
void System.Diagnostics.Metrics.MetricsEventSource:.cctor () | ||
void System.Diagnostics.Metrics.MetricsEventSource:.ctor () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yay! A decent number of these are gone now.
stdErr: Error: apkdiff: File 'assemblies/System.Diagnostics.DiagnosticSource.dll' has changed by -3,463 bytes (-38.24 %). This exceeds the threshold of 5.00 %. Error: apkdiff: Size regression occured, 1 check(s) failed.
"assemblies/System.Diagnostics.DiagnosticSource.dll": { | ||
"Size": 12520 | ||
"Size": 9057 | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a nice bonus:
stdErr: Error: apkdiff: File 'assemblies/System.Diagnostics.DiagnosticSource.dll' has changed by -3,463 bytes (-38.24 %). This exceeds the threshold of 5.00 %.
Error: apkdiff: Size regression occured, 1 check(s) failed.
tests/Mono.Android-Tests/Runtime-Microsoft.Android.Sdk/System/AppContextTests.cs
Show resolved
Hide resolved
wip commit message: Context: https://github.com/dotnet/runtime/commit/fecf3eeffd3650566555e15292f9df0d3abcdfc6
Context: https://github.com/dotnet/runtime/commit/3aeefbdd5e975e287effaa8670422837dc661d68
Context: https://github.com/dotnet/runtime/issues/89880
In dotnet/runtime two new feature switches were added in order to
improve startup performance on Android:
* `System.Diagnostics.Metrics.Meter.IsSupported`: disables
`System.Diagnostics.Metrics` support for `HttpClient`, etc.
* `Microsoft.Extensions.DependencyInjection.DisableDynamicEngine`:
after the second call to retrieve a service from a dependency
injection container, `System.Reflection.Emit` is used to improve
performance of repeated calls.
We also have the existing switch:
* `Switch.System.Reflection.ForceInterpretedInvoke`: after the
second call to `MethodInfo.Invoke()` or `ConstructorInfo.Invoke()`,
`System.Reflection.Emit` is used to improve performance of
repeated calls.
Introduce two new MSBuild properties:
* `$(AndroidAvoidEmitForPerformance)` to toggle both
`Microsoft.Extensions.DependencyInjection.DisableDynamicEngine` and
`Switch.System.Reflection.ForceInterpretedInvoke`. This is a public
property that defaults to `true`.
* `$(_SystemDiagnosticsMetricsMeterIsSupported)` to toggle
`System.Diagnostics.Metrics.Meter.IsSupported`. This is a private
property that defaults to `false`.
I added a test to check `System.Diagnostics.Metrics.Meter.IsSupported`
at runtime. I did not do this with Microsoft.Extensions, as we'd have
to add a reference to the NuGet package and track its version for
nightly builds.
I also updated the AOT profile, and some
`System.Diagnostics.Metrics.Meter` API calls are now gone:
bool System.Diagnostics.Metrics.Meter:AddInstrument (System.Diagnostics.Metrics.Instrument)
object System.Diagnostics.Metrics.Instrument:get_SyncObject ()
System.Diagnostics.Metrics.Counter`1<long> System.Diagnostics.Metrics.Meter:CreateCounter (string,string,string,System.Collections.Generic.IEnumerable`1<System.Collections.Generic.KeyValuePair`2<string, object>>)
System.Diagnostics.Metrics.Counter`1<long> System.Diagnostics.Metrics.Meter:CreateCounter (string,string,string)
void System.Diagnostics.Metrics.MeterListener:.cctor ()
void System.Diagnostics.Metrics.MetricsEventSource:.cctor ()
void System.Diagnostics.Metrics.MetricsEventSource:.ctor () |
@@ -38,7 +38,17 @@ See: https://github.com/dotnet/runtime/blob/b13715b6984889a709ba29ea8a1961db469f | |||
Trim="true" /> | |||
<!-- https://github.com/dotnet/runtime/blob/211cdd011f19a51b7092d8365e11e774a8280afb/src/libraries/System.Private.CoreLib/src/System/LocalAppContextSwitches.cs#L52 --> | |||
<RuntimeHostConfigurationOption Include="Switch.System.Reflection.ForceInterpretedInvoke" | |||
Value="$(_SystemReflectionForceInterpretedInvoke)" | |||
Value="$(AndroidAvoidEmitForPerformance)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This gives me some pause: Do we want/need/should we allow Switch.System.Reflection.ForceInterpretedInvoke
and Microsoft.Extensions.DependencyInjection.DisableDynamicEngine
to be handled separately?
$(_SystemDiagnosticsMetricsMeterIsSupported)
allows System.Diagnostics.Metrics.Meter.IsSupported
to be handled separately.
I wonder if we should leave this line unchanged -- continue using Value="$(_SystemReflectionForceInterpretedInvoke)"
-- and also have the default values of $(_SystemReflectionForceInterpretedInvoke)
and $(_SystemReflectionForceInterpretedInvoke)
be the opposite of $(AndroidAvoidEmitForPerformance)
.
(Aside: how concerned should I be that one of these switches has a Switch.
prefix, while the other doesn't?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the reason to put both under a single property is simplicity. I can't really think of a good reason to toggle them at all -- let alone independently.
(Aside: how concerned should I be that one of these switches has a Switch. prefix, while the other doesn't?)
Switch.
seems weird to me, too, but they have a mix of both in this file:
I think it depends on which team implemented it...
* main: [Xamarin.Android.Build.Tasks] feature switch defaults for fast startup (dotnet#8347) Localized file check-in by OneLocBuild Task (dotnet#8358)
Context: dotnet/runtime@fecf3ee
Context: dotnet/runtime@3aeefbd
Context: dotnet/runtime#89880
In dotnet/runtime two new feature switches were added in order to improve startup performance on Android:
System.Diagnostics.Metrics.Meter.IsSupported
: disablesSystem.Diagnostics.Metrics
support forHttpClient
, etc.Microsoft.Extensions.DependencyInjection.DisableDynamicEngine
: after the second call to retrieve a service from a dependency injection container,System.Reflection.Emit
is used to improve performance of repeated calls.We also have the existing switch:
Switch.System.Reflection.ForceInterpretedInvoke
: after the second call toMethodInfo.Invoke()
orConstructorInfo.Invoke()
,System.Reflection.Emit
is used to improve performance of repeated calls.Introduce two new MSBuild properties:
$(AvoidEmitForPerformance)
to toggle bothMicrosoft.Extensions.DependencyInjection.DisableDynamicEngine
andSwitch.System.Reflection.ForceInterpretedInvoke
. This is a public property that defaults totrue
, matching a property of the same name used somewhere in ASP.NET.$(_SystemDiagnosticsMetricsMeterIsSupported)
to toggleSystem.Diagnostics.Metrics.Meter.IsSupported
. This is a private property that defaults tofalse
.I added a test to check
System.Diagnostics.Metrics.Meter.IsSupported
at runtime. I did not do this with Microsoft.Extensions, as we'd have to add a reference to the NuGet package and track its version for nightly builds.I also updated the AOT profile, and some
System.Diagnostics.Metrics.Meter
API calls are gone now: