Skip to content

Conversation

@jonathanpeppers
Copy link
Member

@jonathanpeppers jonathanpeppers commented Jan 8, 2020

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

@jonathanpeppers jonathanpeppers force-pushed the remove-iterators branch 3 times, most recently from c4e983e to f713f10 Compare January 13, 2020 22:44
@dotnet dotnet deleted a comment from azure-pipelines bot Jan 13, 2020
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
@jonathanpeppers jonathanpeppers marked this pull request as ready for review January 15, 2020 17:11
* 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
@jonathanpeppers
Copy link
Member Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jonpryor jonpryor merged commit 4e389c4 into dotnet:master Jan 21, 2020
@jonathanpeppers jonathanpeppers deleted the remove-iterators branch January 21, 2020 21:43
@github-actions github-actions bot locked and limited conversation to collaborators Jan 24, 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