Skip to content

[Java.Interop.Tools.Cecil] remove System.Linq in IsSubclassOf #577

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

Merged
merged 1 commit into from
Feb 21, 2020

Conversation

jonathanpeppers
Copy link
Member

Using the Mono profiler, I found:

Allocation summary
    Bytes      Count  Average Type name
  7636736      59662      128 System.Func<Mono.Cecil.TypeDefinition,System.Boolean>
  3685952      57593       64 Java.Interop.Tools.Cecil.TypeDefinitionRocks.<GetTypeAndBaseTypes>d__3

The stack traces of these are from:

2498944 bytes from:
    Xamarin.Android.Tasks.GenerateJavaStubs:Run (Java.Interop.Tools.Cecil.DirectoryAssemblyResolver)
    Xamarin.Android.Tasks.ManifestDocument:Merge (Microsoft.Build.Utilities.TaskLoggingHelper,Java.Interop.Tools.Cecil.TypeDefinitionCache,System.Collections.Generic.List`1<Mono.Cecil.TypeDefinition>,string,bool,string,System.Collections.Generic.IEnumerable`1<string>)
    Xamarin.Android.Tasks.ManifestDocument:GetGenerator (Mono.Cecil.TypeDefinition,Java.Interop.Tools.Cecil.TypeDefinitionCache)
    Java.Interop.Tools.Cecil.TypeDefinitionRocks:IsSubclassOf (Mono.Cecil.TypeDefinition,string,Java.Interop.Tools.Cecil.TypeDefinitionCache)
    (wrapper alloc) object:ProfilerAllocSmall (intptr,intptr)
    (wrapper managed-to-native) object:__icall_wrapper_mono_profiler_raise_gc_allocation (object)
...
1273344 bytes from:
    Xamarin.Android.Tasks.ManifestDocument:Merge (Microsoft.Build.Utilities.TaskLoggingHelper,Java.Interop.Tools.Cecil.TypeDefinitionCache,System.Collections.Generic.List`1<Mono.Cecil.TypeDefinition>,string,bool,string,System.Collections.Generic.IEnumerable`1<string>)
    Xamarin.Android.Tasks.ManifestDocument:GetGenerator (Mono.Cecil.TypeDefinition,Java.Interop.Tools.Cecil.TypeDefinitionCache)
    Java.Interop.Tools.Cecil.TypeDefinitionRocks:IsSubclassOf (Mono.Cecil.TypeDefinition,string,Java.Interop.Tools.Cecil.TypeDefinitionCache)
    Java.Interop.Tools.Cecil.TypeDefinitionRocks:GetTypeAndBaseTypes (Mono.Cecil.TypeDefinition,Java.Interop.Tools.Cecil.TypeDefinitionCache)
    (wrapper alloc) object:ProfilerAllocSmall (intptr,intptr)
    (wrapper managed-to-native) object:__icall_wrapper_mono_profiler_raise_gc_allocation (object)

This IsSubclassOf method gets called ~40K times during a build:

Method call summary
Total(ms) Self(ms)      Calls Method name
     2431      117      43493 Java.Interop.Tools.Cecil.TypeDefinitionRocks:IsSubclassOf (Mono.Cecil.TypeDefinition,string,Java.Interop.Tools.Cecil.TypeDefinitionCache)

Reviewing IsSubclassOf we can just remove the System.Linq usage and
use a foreach loop instead.

The results of building the Xamarin.Forms integration project on
Windows:

Before:
559 ms  GenerateJavaStubs                          1 calls
After:
535 ms  GenerateJavaStubs                          1 calls

A ~24ms savings is pretty good for a small app.

I suspect it would have even better improvements on macOS / Mono, due
to what I saw in: dotnet/android#4260

Using the Mono profiler, I found:

    Allocation summary
        Bytes      Count  Average Type name
      7636736      59662      128 System.Func<Mono.Cecil.TypeDefinition,System.Boolean>
      3685952      57593       64 Java.Interop.Tools.Cecil.TypeDefinitionRocks.<GetTypeAndBaseTypes>d__3

The stack traces of these are from:

    2498944 bytes from:
        Xamarin.Android.Tasks.GenerateJavaStubs:Run (Java.Interop.Tools.Cecil.DirectoryAssemblyResolver)
        Xamarin.Android.Tasks.ManifestDocument:Merge (Microsoft.Build.Utilities.TaskLoggingHelper,Java.Interop.Tools.Cecil.TypeDefinitionCache,System.Collections.Generic.List`1<Mono.Cecil.TypeDefinition>,string,bool,string,System.Collections.Generic.IEnumerable`1<string>)
        Xamarin.Android.Tasks.ManifestDocument:GetGenerator (Mono.Cecil.TypeDefinition,Java.Interop.Tools.Cecil.TypeDefinitionCache)
        Java.Interop.Tools.Cecil.TypeDefinitionRocks:IsSubclassOf (Mono.Cecil.TypeDefinition,string,Java.Interop.Tools.Cecil.TypeDefinitionCache)
        (wrapper alloc) object:ProfilerAllocSmall (intptr,intptr)
        (wrapper managed-to-native) object:__icall_wrapper_mono_profiler_raise_gc_allocation (object)
    ...
    1273344 bytes from:
        Xamarin.Android.Tasks.ManifestDocument:Merge (Microsoft.Build.Utilities.TaskLoggingHelper,Java.Interop.Tools.Cecil.TypeDefinitionCache,System.Collections.Generic.List`1<Mono.Cecil.TypeDefinition>,string,bool,string,System.Collections.Generic.IEnumerable`1<string>)
        Xamarin.Android.Tasks.ManifestDocument:GetGenerator (Mono.Cecil.TypeDefinition,Java.Interop.Tools.Cecil.TypeDefinitionCache)
        Java.Interop.Tools.Cecil.TypeDefinitionRocks:IsSubclassOf (Mono.Cecil.TypeDefinition,string,Java.Interop.Tools.Cecil.TypeDefinitionCache)
        Java.Interop.Tools.Cecil.TypeDefinitionRocks:GetTypeAndBaseTypes (Mono.Cecil.TypeDefinition,Java.Interop.Tools.Cecil.TypeDefinitionCache)
        (wrapper alloc) object:ProfilerAllocSmall (intptr,intptr)
        (wrapper managed-to-native) object:__icall_wrapper_mono_profiler_raise_gc_allocation (object)

This `IsSubclassOf` method gets called ~40K times during a build:

    Method call summary
    Total(ms) Self(ms)      Calls Method name
         2431      117      43493 Java.Interop.Tools.Cecil.TypeDefinitionRocks:IsSubclassOf (Mono.Cecil.TypeDefinition,string,Java.Interop.Tools.Cecil.TypeDefinitionCache)

Reviewing `IsSubclassOf` we can just remove the System.Linq usage and
use a `foreach` loop instead.

The results of building the Xamarin.Forms integration project on
Windows:

    Before:
    559 ms  GenerateJavaStubs                          1 calls
    After:
    535 ms  GenerateJavaStubs                          1 calls

A ~24ms savings is pretty good for a small app.

I suspect it would have even better improvements on macOS / Mono, due
to what I saw in: dotnet/android#4260
@jonpryor jonpryor merged commit 9a01c9b into dotnet:master Feb 21, 2020
@jonathanpeppers jonathanpeppers deleted the issubclassof-linq branch February 21, 2020 18:13
jonpryor pushed a commit that referenced this pull request Feb 24, 2020
Using the Mono profiler, I found:

	Allocation summary
	    Bytes      Count  Average Type name
	  7636736      59662      128 System.Func<Mono.Cecil.TypeDefinition,System.Boolean>
	  3685952      57593       64 Java.Interop.Tools.Cecil.TypeDefinitionRocks.<GetTypeAndBaseTypes>d__3

The stack traces of these are from:

	2498944 bytes from:
	    Xamarin.Android.Tasks.GenerateJavaStubs:Run (Java.Interop.Tools.Cecil.DirectoryAssemblyResolver)
	    Xamarin.Android.Tasks.ManifestDocument:Merge (Microsoft.Build.Utilities.TaskLoggingHelper,Java.Interop.Tools.Cecil.TypeDefinitionCache,System.Collections.Generic.List`1<Mono.Cecil.TypeDefinition>,string,bool,string,System.Collections.Generic.IEnumerable`1<string>)
	    Xamarin.Android.Tasks.ManifestDocument:GetGenerator (Mono.Cecil.TypeDefinition,Java.Interop.Tools.Cecil.TypeDefinitionCache)
	    Java.Interop.Tools.Cecil.TypeDefinitionRocks:IsSubclassOf (Mono.Cecil.TypeDefinition,string,Java.Interop.Tools.Cecil.TypeDefinitionCache)
	    (wrapper alloc) object:ProfilerAllocSmall (intptr,intptr)
	    (wrapper managed-to-native) object:__icall_wrapper_mono_profiler_raise_gc_allocation (object)
	...
	1273344 bytes from:
	    Xamarin.Android.Tasks.ManifestDocument:Merge (Microsoft.Build.Utilities.TaskLoggingHelper,Java.Interop.Tools.Cecil.TypeDefinitionCache,System.Collections.Generic.List`1<Mono.Cecil.TypeDefinition>,string,bool,string,System.Collections.Generic.IEnumerable`1<string>)
	    Xamarin.Android.Tasks.ManifestDocument:GetGenerator (Mono.Cecil.TypeDefinition,Java.Interop.Tools.Cecil.TypeDefinitionCache)
	    Java.Interop.Tools.Cecil.TypeDefinitionRocks:IsSubclassOf (Mono.Cecil.TypeDefinition,string,Java.Interop.Tools.Cecil.TypeDefinitionCache)
	    Java.Interop.Tools.Cecil.TypeDefinitionRocks:GetTypeAndBaseTypes (Mono.Cecil.TypeDefinition,Java.Interop.Tools.Cecil.TypeDefinitionCache)
	    (wrapper alloc) object:ProfilerAllocSmall (intptr,intptr)
	    (wrapper managed-to-native) object:__icall_wrapper_mono_profiler_raise_gc_allocation (object)

This `TypeDefinitionRocks.IsSubclassOf()` method gets called ~40K
times during a build:

	Method call summary
	Total(ms) Self(ms)      Calls Method name
	     2431      117      43493 Java.Interop.Tools.Cecil.TypeDefinitionRocks:IsSubclassOf (Mono.Cecil.TypeDefinition,string,Java.Interop.Tools.Cecil.TypeDefinitionCache)

Reviewing `IsSubclassOf()` we can just remove the System.Linq usage
and use a `foreach` loop instead.

The results of building the Xamarin.Forms integration project on
Windows:

  * Before:

        559 ms  GenerateJavaStubs                          1 calls

  * After:

        535 ms  GenerateJavaStubs                          1 calls

A ~24ms savings is pretty good for a small app.

I suspect it would have even better improvements on macOS / Mono, due
to what I saw in: dotnet/android#4260
@github-actions github-actions bot locked and limited conversation to collaborators Apr 13, 2024
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