Skip to content

[android] .NET 8 performance regression in System.Reflection.MethodInfo/ConstructorInfo.Invoke() #83893

Closed
dotnet/android
#7972
@jonathanpeppers

Description

@jonathanpeppers

Description

.NET 7 added a code path that uses System.Reflection.Emit for ConstructorInfo/MethodInfo for coreclr. This makes sense for throughput, scenarios like ASP.NET.

On mobile, however, we are more concerned about a fast startup. I found that we may have accidentally introduced this behavior for Mono (or at least Android) in .NET 8:

#72717

In .NET MAUI apps that heavily use things like data-binding, Microsoft.Extensions.DI, etc. It appears that this change noticeably slows down startup.

In my benchmark, I setup a "first run" / "cold start" scenario:

Version Method Mean Allocated
.NET 7 ContructorInfo_Invoke 530.5 us 552 B
.NET 7 MethodInfo_Invoke 457.6 us 128 B
.NET 8 ContructorInfo_Invoke 607.7 us 4.09 KB
.NET 8 MethodInfo_Invoke 1,202.1 us 2.38 KB

/cc @steveisok

Reproduction Steps

Try my instructions here: https://github.com/jonathanpeppers/BenchmarkDotNet-Android/tree/System.Reflection

Expected behavior

We probably shouldn't hit the S.R.E codepath by default on Android.

We should have a flag to opt into it? It may be useful for some apps, although it appears to slow down startup in the apps I've tried.

Actual behavior

We hit the S.R.E codepath by default on Android.

Regression?

Yes, it appears .NET 7 does not have this issue.

Known Workarounds

Use .NET 7?

Configuration

.NET SDK: 8.0.100-preview.3.23170.5

Other information

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions