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

[Xamarin.Android.Build.Tasks] Debug-mode linker improvements #2590

Closed
wants to merge 1 commit into
base: master
from

Conversation

Projects
None yet
2 participants
@jonathanpeppers
Copy link
Contributor

jonathanpeppers commented Jan 4, 2019

StripEmbeddedLibraries

I have noticed the support libraries from NuGet are fairly large. In
total I have seen them around 8MB in size! Much of their size is not
in fact managed code, but the Android resources, jar files, etc.
contained within them.

For example, if you look at the size of
__AndroidLibraryProjects__.zip embedded in
Xamarin.Android.Support.v7.MediaRouter 27.0.2.1:

592534 __AndroidLibraryProjects__.zip

~0.5MB in a single assembly!

So I did an experiment to run the StripEmbeddedLibraries linker step
during a debug build.

Before:
9.66 MB total
  22064 FormsViewGroup.dll
 101376 HelloForms.Android.dll
   6144 HelloForms.dll
  35416 Xamarin.Android.Arch.Core.Common.dll
  55904 Xamarin.Android.Arch.Lifecycle.Common.dll
  31840 Xamarin.Android.Arch.Lifecycle.Runtime.dll
  77432 Xamarin.Android.Support.Animated.Vector.Drawable.dll
 151648 Xamarin.Android.Support.Annotations.dll
1699408 Xamarin.Android.Support.Compat.dll
 545880 Xamarin.Android.Support.Core.UI.dll
 228952 Xamarin.Android.Support.Core.Utils.dll
 744528 Xamarin.Android.Support.Design.dll
 409688 Xamarin.Android.Support.Fragment.dll
 733280 Xamarin.Android.Support.Media.Compat.dll
 322648 Xamarin.Android.Support.Transition.dll
  41544 Xamarin.Android.Support.v4.dll
1995872 Xamarin.Android.Support.v7.AppCompat.dll
  60504 Xamarin.Android.Support.v7.CardView.dll
 780896 Xamarin.Android.Support.v7.MediaRouter.dll
  68184 Xamarin.Android.Support.v7.Palette.dll
 851552 Xamarin.Android.Support.v7.RecyclerView.dll
  61024 Xamarin.Android.Support.Vector.Drawable.dll
 673336 Xamarin.Forms.Core.dll
 334416 Xamarin.Forms.Platform.Android.dll
  16960 Xamarin.Forms.Platform.dll
  85560 Xamarin.Forms.Xaml.dll

After:
5.60 MB total
  12800 FormsViewGroup.dll
 101376 HelloForms.Android.dll
   6144 HelloForms.dll
  16896 Xamarin.Android.Arch.Core.Common.dll
  28160 Xamarin.Android.Arch.Lifecycle.Common.dll
  13824 Xamarin.Android.Arch.Lifecycle.Runtime.dll
  32256 Xamarin.Android.Support.Animated.Vector.Drawable.dll
 118784 Xamarin.Android.Support.Annotations.dll
1142272 Xamarin.Android.Support.Compat.dll
 301568 Xamarin.Android.Support.Core.UI.dll
 123904 Xamarin.Android.Support.Core.Utils.dll
 350208 Xamarin.Android.Support.Design.dll
 231936 Xamarin.Android.Support.Fragment.dll
 411136 Xamarin.Android.Support.Media.Compat.dll
 137216 Xamarin.Android.Support.Transition.dll
  28672 Xamarin.Android.Support.v4.dll
 947200 Xamarin.Android.Support.v7.AppCompat.dll
  28672 Xamarin.Android.Support.v7.CardView.dll
 181248 Xamarin.Android.Support.v7.MediaRouter.dll
  35328 Xamarin.Android.Support.v7.Palette.dll
 497152 Xamarin.Android.Support.v7.RecyclerView.dll
  20480 Xamarin.Android.Support.Vector.Drawable.dll
 673336 Xamarin.Forms.Core.dll
 334416 Xamarin.Forms.Platform.Android.dll
  16960 Xamarin.Forms.Platform.dll
  85560 Xamarin.Forms.Xaml.dll

This equates to:

  • 4.0 MB less assemblies shipped to the device during deployment!
  • 4.0 MB less assemblies loaded at startup!

Changes to make this happen:

  • For this to work properly, I had to change StripEmbeddedLibraries
    to operate on Skip assemblies. If the assembly is going to get
    stripped, then its action will change to Save. This now means this
    pass has to run last, so a comment seemed ideal in the list of
    linker steps.

Results

The same "Hello World" Xamarin.Forms project had a minor improvement
to the initial deployment:

Before:
2730 ms  InstallPackageAssemblies                   1 calls
After:
2549 ms  InstallPackageAssemblies                   1 calls

Saved ~200ms during the first deployment.

And if you review the size of the assemblies copied during
InstallPackageAssemblies:

Before:
100% ... 10332kb of 10332kb copied
After:
100% ... 6173kb of 6173kb copied

TODO: I need to measure startup time impact.

@jonathanpeppers

This comment has been minimized.

Copy link
Contributor

jonathanpeppers commented Jan 4, 2019

Build logs: Logs.zip

Mainly sending this to "see what breaks", I want to test it a little more, hence the do-not-merge label.

I also want to measure the impact to startup time for this.

@jonathanpeppers jonathanpeppers force-pushed the jonathanpeppers:debug-improvements-linker branch from b03e219 to f5fa267 Jan 7, 2019

@jonpryor

This comment has been minimized.

Copy link
Contributor

jonpryor commented Jan 9, 2019

build

@jonathanpeppers

This comment has been minimized.

Copy link
Contributor

jonathanpeppers commented Jan 10, 2019

I'm going to rework this, and only do the StripEmbeddedLibraries portion for now.

[Xamarin.Android.Build.Tasks] Debug-mode linker improvements
~~ StripEmbeddedLibraries ~~

I have noticed the support libraries from NuGet are fairly large. In
total I have seen them around 8MB in size! Much of their size is not
in fact managed code, but the Android resources, jar files, etc.
contained within them.

For example, if you look at the size of
`__AndroidLibraryProjects__.zip` embedded in
Xamarin.Android.Support.v7.MediaRouter 27.0.2.1:

    592534 __AndroidLibraryProjects__.zip

~0.5MB in a single assembly!

So I did an experiment to run the `StripEmbeddedLibraries` linker step
during a debug build.

    Before:
    9.66 MB total
      22064 FormsViewGroup.dll
     101376 HelloForms.Android.dll
       6144 HelloForms.dll
      35416 Xamarin.Android.Arch.Core.Common.dll
      55904 Xamarin.Android.Arch.Lifecycle.Common.dll
      31840 Xamarin.Android.Arch.Lifecycle.Runtime.dll
      77432 Xamarin.Android.Support.Animated.Vector.Drawable.dll
     151648 Xamarin.Android.Support.Annotations.dll
    1699408 Xamarin.Android.Support.Compat.dll
     545880 Xamarin.Android.Support.Core.UI.dll
     228952 Xamarin.Android.Support.Core.Utils.dll
     744528 Xamarin.Android.Support.Design.dll
     409688 Xamarin.Android.Support.Fragment.dll
     733280 Xamarin.Android.Support.Media.Compat.dll
     322648 Xamarin.Android.Support.Transition.dll
      41544 Xamarin.Android.Support.v4.dll
    1995872 Xamarin.Android.Support.v7.AppCompat.dll
      60504 Xamarin.Android.Support.v7.CardView.dll
     780896 Xamarin.Android.Support.v7.MediaRouter.dll
      68184 Xamarin.Android.Support.v7.Palette.dll
     851552 Xamarin.Android.Support.v7.RecyclerView.dll
      61024 Xamarin.Android.Support.Vector.Drawable.dll
     673336 Xamarin.Forms.Core.dll
     334416 Xamarin.Forms.Platform.Android.dll
      16960 Xamarin.Forms.Platform.dll
      85560 Xamarin.Forms.Xaml.dll

    After:
    5.60 MB total
      12800 FormsViewGroup.dll
     101376 HelloForms.Android.dll
       6144 HelloForms.dll
      16896 Xamarin.Android.Arch.Core.Common.dll
      28160 Xamarin.Android.Arch.Lifecycle.Common.dll
      13824 Xamarin.Android.Arch.Lifecycle.Runtime.dll
      32256 Xamarin.Android.Support.Animated.Vector.Drawable.dll
     118784 Xamarin.Android.Support.Annotations.dll
    1142272 Xamarin.Android.Support.Compat.dll
     301568 Xamarin.Android.Support.Core.UI.dll
     123904 Xamarin.Android.Support.Core.Utils.dll
     350208 Xamarin.Android.Support.Design.dll
     231936 Xamarin.Android.Support.Fragment.dll
     411136 Xamarin.Android.Support.Media.Compat.dll
     137216 Xamarin.Android.Support.Transition.dll
      28672 Xamarin.Android.Support.v4.dll
     947200 Xamarin.Android.Support.v7.AppCompat.dll
      28672 Xamarin.Android.Support.v7.CardView.dll
     181248 Xamarin.Android.Support.v7.MediaRouter.dll
      35328 Xamarin.Android.Support.v7.Palette.dll
     497152 Xamarin.Android.Support.v7.RecyclerView.dll
      20480 Xamarin.Android.Support.Vector.Drawable.dll
     673336 Xamarin.Forms.Core.dll
     334416 Xamarin.Forms.Platform.Android.dll
      16960 Xamarin.Forms.Platform.dll
      85560 Xamarin.Forms.Xaml.dll

This equates to:
- 4.0 MB less assemblies shipped to the device during deployment!
- 4.0 MB less assemblies loaded at startup!

Changes to make this happen:

- For this to work properly, I had to change `StripEmbeddedLibraries`
  to operate on `Skip` assemblies. If the assembly is going to get
  stripped, then its action will change to `Save`. This now means this
  pass has to run *last*, so a comment seemed ideal in the list of
  linker steps.

~~ Results ~~

The same "Hello World" Xamarin.Forms project had a minor improvement
to the initial deployment:

    Before:
    2730 ms  InstallPackageAssemblies                   1 calls
    After:
    2549 ms  InstallPackageAssemblies                   1 calls

Saved ~200ms during the first deployment.

And if you review the size of the assemblies copied during
`InstallPackageAssemblies`:

    Before:
    100% ... 10332kb of 10332kb copied
    After:
    100% ... 6173kb of 6173kb copied

TODO: I need to measure startup time impact.

@jonathanpeppers jonathanpeppers force-pushed the jonathanpeppers:debug-improvements-linker branch from f5fa267 to e4fbbdb Jan 10, 2019

@jonathanpeppers

This comment has been minimized.

Copy link
Contributor

jonathanpeppers commented Jan 10, 2019

So there is a bit of slowdown here:

Before:
 554 ms  LinkAssemblies                             1 calls
After:
1248 ms  LinkAssemblies                             1 calls

If we save ~200ms on deploy time, and it looks like it saves ~10ms in startup time (from what I measured on a Pixel 2) this tradeoff isn't quite worth it.

I will close this for now, and come back to it if it makes sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment