Skip to content

Conversation

@jonathanpeppers
Copy link
Member

Comparing performance of .NET 9 vs .NET 10, I noticed something very odd stand out!

.NET 9:
14.94ms System.Private.CoreLib!System.Type.GetType(string...
.NET 10:
53.57ms System.Private.CoreLib!System.Type.GetType(string...

Was Type.GetType() really that much slower in .NET 10?

After some testing, my tests found that this was not the case when I tested Type.GetType() in isolation.

So I added some logging to JNIEnvInit to see what was going on:

var sw = new System.Diagnostics.Stopwatch ();
sw.Start ();
var type = TypeGetType (typeName);
sw.Stop ();
Logger.Log (LogLevel.Debug, "monodroid", FormattableString.Invariant ($"foo: Type.GetType() took {sw.ElapsedMilliseconds} ms, with type '{typeName}'."));

And got this result!

08-14 10:57:28.998  8435  8435 D monodroid: foo: Type.GetType() took 17 ms, with type 'helloandroid.MainActivity, helloandroid'.
08-14 10:57:29.046  8435  8435 D monodroid: foo: Type.GetType() took 37 ms, with type 'Java.Interop.TypeManager+JavaTypeManager, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.

37ms is a lot!

Then I noticed the string has the full assembly identity:

Java.Interop.TypeManager+JavaTypeManager, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null

But it should actually be:

Java.Interop.TypeManager+JavaTypeManager, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065

The stack trace of Type.GetType() shows that there must be some new assembly name validation going on. This certainly doesn't match, so we must be hitting a slow path!

I just removed the assembly identity from the string, and now we get:

--08-14 10:57:29.046  8435  8435 D monodroid: foo: Type.GetType() took 37 ms, with type 'Java.Interop.TypeManager+JavaTypeManager, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
++08-14 11:19:32.087 10011 10011 D monodroid: foo: Type.GetType() took 1 ms, with type 'Java.Interop.TypeManager+JavaTypeManager, Mono.Android'.

It appears we always had this code, but maybe in the past no assembly validation was done? That is my current theory.

Comparing performance of .NET 9 vs .NET 10, I noticed something very
odd stand out!

    .NET 9:
    14.94ms System.Private.CoreLib!System.Type.GetType(string...
    .NET 10:
    53.57ms System.Private.CoreLib!System.Type.GetType(string...

Was `Type.GetType()` really that much slower in .NET 10?

After some testing, my tests found that this was not the case when I
tested `Type.GetType()` in isolation.

So I added some logging to `JNIEnvInit` to see what was going on:

    var sw = new System.Diagnostics.Stopwatch ();
    sw.Start ();
    var type = TypeGetType (typeName);
    sw.Stop ();
    Logger.Log (LogLevel.Debug, "monodroid", FormattableString.Invariant ($"foo: Type.GetType() took {sw.ElapsedMilliseconds} ms, with type '{typeName}'."));

And got this result!

    08-14 10:57:28.998  8435  8435 D monodroid: foo: Type.GetType() took 17 ms, with type 'helloandroid.MainActivity, helloandroid'.
    08-14 10:57:29.046  8435  8435 D monodroid: foo: Type.GetType() took 37 ms, with type 'Java.Interop.TypeManager+JavaTypeManager, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.

37ms is a lot!

Then I noticed the string has the full assembly identity:

    Java.Interop.TypeManager+JavaTypeManager, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null

But it should actually be:

    Java.Interop.TypeManager+JavaTypeManager, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065

The stack trace of `Type.GetType()` shows that there must be some new
assembly name validation going on. This certainly doesn't match, so we
must be hitting a slow path!

I just removed the assembly identity from the string, and now we get:

```diff
--08-14 10:57:29.046  8435  8435 D monodroid: foo: Type.GetType() took 37 ms, with type 'Java.Interop.TypeManager+JavaTypeManager, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
++08-14 11:19:32.087 10011 10011 D monodroid: foo: Type.GetType() took 1 ms, with type 'Java.Interop.TypeManager+JavaTypeManager, Mono.Android'.
```

It appears we always had this code, but maybe in the past no assembly
validation was done? That is my current theory.
@jonathanpeppers jonathanpeppers enabled auto-merge (squash) August 14, 2025 19:47
@jonathanpeppers jonathanpeppers merged commit 4576503 into main Aug 14, 2025
59 checks passed
@jonathanpeppers jonathanpeppers deleted the dev/peppers/TypeManager.java branch August 14, 2025 20:39
@github-actions github-actions bot locked and limited conversation to collaborators Sep 14, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants