-
Notifications
You must be signed in to change notification settings - Fork 564
[Mono.Android] remove IEnumerable iterators called at startup #4102
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
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
c4e983e to
f713f10
Compare
f713f10 to
35cb340
Compare
jonpryor
pushed a commit
to dotnet/java-interop
that referenced
this pull request
Jan 15, 2020
Context: dotnet/android#4102 When profiling with `adb shell setprop debug.mono.profile log:alloc` against the [Xamarin.Forms integration project in xamarin-android][0], 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 100K of memory allocations are a bit much, so seemed like it might help to reduce these. To reduce the allocations, update `JniTypeManager.GetTypeSignature()` to *not* call `JniTypeManager.GetTypeSignatures()` (note: plural) and instead "duplicate" the `GetTypeSignatures()` logic, optimizing for a single return value. `JniTypeManager.GetTypeSignature()` calls the new method `JniTypeManager.GetSimpleReference()`. There are thus two methods of consequence derived types can override: partial class JniTypeManager { protected virtual string GetSimpleReference (Type type); protected virtual IEnumerable<string> GetSimpleReferences (Type type); } Which one should be overridden? `GetSimpleReference()` is implemented in terms of `GetSimpleReferences()`, so the only method that is "required" to be overridden is `GetSimpleReferences()`. However, when concerned about performance, *both* methods should be overridden, taking care to ensure that `GetSimpleReference()` returns the *first* value that `GetSimpleReferences()` would 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][1] that was probably originally used for netstandard 1.x compatibility. ~~ Results ~~ After [updating xamarin-android][2] to override `JniTypeManager.GetSimpleReference()`, 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: * Working Set : 71008256 * Private Bytes : 601202688 * Virtual Bytes : 1306873856 * After: * Working Set : 70774784 * Private Bytes : 552910848 * Virtual Bytes : 1302822912 Then the total GC summary: * Before: Event: GC allocations : 9340 * After: Event: GC allocations : 8867 ~473 allocations are saved. [0]: https://github.com/xamarin/xamarin-android/tree/master/tests/Xamarin.Forms-Performance-Integration [1]: https://github.com/mono/mono/blob/c5b88ec4f323f2bdb7c7d0a595ece28dae66579c/mcs/class/referencesource/mscorlib/system/reflection/introspectionextensions.cs#L24 [2]: dotnet/android#4102
35cb340 to
a00a0f7
Compare
* Bump to xamarin/java.interop/master@621e297 Changes: dotnet/java-interop@4565369...621e297 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
a00a0f7 to
a06ab80
Compare
Member
Author
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Bump to xamarin/java.interop/master@621e297
Changes: dotnet/java-interop@4565369...621e297
When profiling with
adb setprop debug.mono.profile log:alloc, Inoticed the following allocations:
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.CreateTypeSignaturesandAndroidTypeManager.GetSimpleReferencesthat return a single valueinstead of an
IEnumerableandyield return.Other general performance changes:
Added
[MethodImpl (MethodImplOptions.AggressiveInlining)]toJniTypeManager.AssertValid. It is called quite frequently.Removed a call to
.GetTypeInfo(), as this was not needed. It wrapsSystem.Typein another type that was probably originally used fornetstandard 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:
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:
Then the total GC summary: