Skip to content

Commit 35cb340

Browse files
[Mono.Android] remove IEnumerable iterators called at startup
When profiling with `adb setprop debug.mono.profile log:alloc`, I noticed the following allocations: Allocation summary Bytes Count Average Type name 84840 505 168 Java.Interop.JniRuntime.JniTypeManager.<CreateGetTypeSignaturesEnumerator>d__11 24096 502 48 Android.Runtime.AndroidTypeManager.<GetSimpleReferences>d__1 This was using the Xamarin.Forms integration project in xamarin-android: https://github.com/xamarin/xamarin-android/tree/master/tests/Xamarin.Forms-Performance-Integration 100K of memory allocations are a bit much, so seemed like it might help to reduce these. I made a version of both `JniTypeManager.CreateTypeSignatures` and `AndroidTypeManager.GetSimpleReferences` that return a single value instead of an `IEnumerable` and `yield return`. Other general performance changes: * Added `[MethodImpl (MethodImplOptions.AggressiveInlining)]` to `JniTypeManager.AssertValid`. It is called quite frequently. * Removed a call to `.GetTypeInfo()`, as this was not needed. It wraps `System.Type` in another type that was probably originally used for netstandard 1.x compatibility. See: https://github.com/mono/mono/blob/c5b88ec4f323f2bdb7c7d0a595ece28dae66579c/mcs/class/referencesource/mscorlib/system/reflection/introspectionextensions.cs#L24 Changes had to be made in both java.interop and xamarin-android for this to work. ~~ Results ~~ I was able to see a startup improvement in a Release build of the Xamarin.Forms integration project on a Pixel 3 XL: Before: 01-08 14:53:34.926 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +779ms 01-08 14:53:38.892 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +764ms 01-08 14:53:42.859 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +753ms 01-08 14:53:46.795 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +748ms 01-08 14:53:50.792 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +764ms 01-08 14:53:54.759 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +756ms 01-08 14:53:58.726 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +764ms 01-08 14:54:02.675 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +749ms 01-08 14:54:06.691 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +759ms 01-08 14:54:10.641 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +749ms Average(ms): 758.5 Std Err(ms): 3.0523215208537 Std Dev(ms): 9.65228815704684 After: 01-08 14:55:56.972 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +772ms 01-08 14:56:00.906 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +741ms 01-08 14:56:05.006 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +741ms 01-08 14:56:08.940 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +748ms 01-08 14:56:12.890 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +747ms 01-08 14:56:16.839 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +753ms 01-08 14:56:20.824 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +757ms 01-08 14:56:24.775 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +746ms 01-08 14:56:28.776 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +747ms 01-08 14:56:32.740 1473 1503 I ActivityTaskManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +748ms Average(ms): 750 Std Err(ms): 2.87904305089189 Std Dev(ms): 9.10433352249844 It seems like this might save ~8ms on startup? There is also a good improvement to memory usage/allocations. Looking at Mono's memory summary: Before: Mono System: Working Set : 71008256 Private Bytes : 601202688 Virtual Bytes : 1306873856 After: Mono System: Working Set : 70774784 Private Bytes : 552910848 Virtual Bytes : 1302822912 Then the total GC summary: Before: Event: GC allocations : 9340 After: Event: GC allocations : 8867
1 parent e22be49 commit 35cb340

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

external/Java.Interop

src/Mono.Android/Android.Runtime/AndroidRuntime.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,11 +229,20 @@ protected override IEnumerable<Type> GetTypesForSimpleReference (string jniSimpl
229229
.Concat (Enumerable.Repeat (t, 1));
230230
}
231231

232-
protected override IEnumerable<string> GetSimpleReferences (Type type)
232+
protected override string GetSimpleReference (Type type)
233233
{
234-
foreach (var simpleRef in base.GetSimpleReferences (type)) {
235-
yield return simpleRef;
234+
var j = JNIEnv.monodroid_typemap_managed_to_java (type.FullName + ", " + type.Assembly.GetName ().Name);
235+
if (j != IntPtr.Zero) {
236+
return Marshal.PtrToStringAnsi (j);
237+
}
238+
if (JNIEnv.IsRunningOnDesktop) {
239+
return JavaNativeTypeManager.ToJniName (type);
236240
}
241+
return null;
242+
}
243+
244+
protected override IEnumerable<string> GetSimpleReferences (Type type)
245+
{
237246
var j = JNIEnv.monodroid_typemap_managed_to_java (type.FullName + ", " + type.Assembly.GetName ().Name);
238247
if (j != IntPtr.Zero) {
239248
yield return Marshal.PtrToStringAnsi (j);

0 commit comments

Comments
 (0)