Skip to content

Commit 3c590a4

Browse files
jonathanpeppersjonpryor
authored andcommitted
[Java.Interop.Tools.Cecil] remove System.Linq in IsSubclassOf (#577)
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
1 parent d1bbed7 commit 3c590a4

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/TypeDefinitionRocks.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Linq;
43

54
using Mono.Cecil;
65

@@ -74,7 +73,12 @@ public static bool IsSubclassOf (this TypeDefinition type, string typeName) =>
7473

7574
public static bool IsSubclassOf (this TypeDefinition type, string typeName, TypeDefinitionCache cache)
7675
{
77-
return type.GetTypeAndBaseTypes (cache).Any (t => t.FullName == typeName);
76+
foreach (var t in type.GetTypeAndBaseTypes (cache)) {
77+
if (t.FullName == typeName) {
78+
return true;
79+
}
80+
}
81+
return false;
7882
}
7983

8084
[Obsolete ("Use the TypeDefinitionCache overload for better performance.")]

0 commit comments

Comments
 (0)