Skip to content

Commit

Permalink
Freshed up java optimization docs
Browse files Browse the repository at this point in the history
Change-Id: I3cb34d8a3695c492b69ffa52543971df60e1cc1c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2855563
Commit-Queue: Andrew Grieve <agrieve@chromium.org>
Auto-Submit: Andrew Grieve <agrieve@chromium.org>
Reviewed-by: Mohamed Heikal <mheikal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#877154}
  • Loading branch information
agrieve authored and Chromium LUCI CQ committed Apr 28, 2021
1 parent f1ece70 commit b000be7
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 41 deletions.
44 changes: 9 additions & 35 deletions build/android/docs/java_optimization.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
# Optimizing Java Code

This doc describes how Java code is optimized in Chrome on Android and how to
deal with issues caused by the optimizer.
deal with issues caused by the optimizer. For tips on how to write optimized
code, see [//docs/speed/binary_size/optimization_advice.md#optimizing-java-code](/docs/speed/binary_size/optimization_advice.md#optimizing-java-code).

[TOC]

## History

When Java code optimization was first added to Chrome the tool used was called
[ProGuard](https://www.guardsquare.com/en/products/proguard). This was used
in public builds until [January 3, 2019](http://crrev.com/c/1394387).

On June 20, 2016, Chrome switched to using an internal fork of ProGuard for
downstream builds because it offered better optimizations for binary size and
method count.

As of [July 20, 2019](https://crrev.com/c/1689877), all Chrome builds have
switched to using [R8](https://r8.googlesource.com/r8), the new tool provided by
Android Studio. R8 provides significant improvements to binary size and method
count over both public and internal ProGuard. R8 uses the same configuration
specification language as ProGuard and supports many of the same rules that
ProGuard did.
## ProGuard vs R8

ProGuard is the original open-source tool used by many Android applications to
perform whole-program bytecode optimization. [R8](https://r8.googlesource.com/r8),
is a re-implementation that is used by Chrome (and the default for Android Studio).
The terms "ProGuard" and "R8" are used interchangeably within Chromium but
generally they're meant to refer to the tool providing Java code optimizations.

Expand All @@ -37,14 +26,11 @@ generally they're meant to refer to the tool providing Java code optimizations.
further through various approaches (ex. inlining, outlining, class merging,
etc).

Chrome relies on ProGuard for keeping Java code size manageable. As of November
2019, a debug build of Chrome has about 3.5x the amount of dex size of a
release build and has 5 `.dex` files (vs. 1 in release).

## Build Process

ProGuard is only enabled for release builds of Chrome because it is a slow build
step. It can also be enabled manually via the GN arg `is_java_debug = false`.
ProGuard is enabled only for release builds of Chrome because it is a slow build
step and breaks Java debugging. It can also be enabled manually via the GN arg:
```is_java_debug = false```

### ProGuard configuration files

Expand All @@ -59,18 +45,6 @@ step generates the `.dex` files for the application. The `proguard` step takes
as input a list of `.jar` files, runs R8/ProGuard on those `.jar` files, and
produces the final `.dex` file(s) that will be packaged into your `.apk`

### Synchronized ProGuard

Some additional steps are required for optimizing code that is shared between
multiple application components (App Bundles and Trichrome). Because ProGuard is
a whole program optimizer, it needs to know about *ALL* code used by the
application or most optimizations won't work as expected.

For synchronized ProGuard, the `.jar` files depended on by all application
components are given to ProGuard to produce a single output. This is then split
with an additional `dexsplitter` step to produce separate `.dex` files for each
dependent application component.

## Deobfuscation

Obfuscation can be turned off for local builds while leaving ProGuard enabled
Expand Down
20 changes: 14 additions & 6 deletions docs/speed/binary_size/optimization_advice.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,12 @@ Googlers: See also [go/abp-performance/apk-size].
binary size by 50kb.
* As of 2019, Chrome for Android (arm32) grows by about 100kb per week.
* To get a feeling for how large existing features are, refer to the
[milestone size breakdowns] and group by "Component".
[milestone size breakdowns] and group by "Component" (Googlers only).
* For non-googlers, run `//tools/binary_size/supersize archive` on a release
build to create a `.size` file, and upload it to [the viewer]

[milestone size breakdowns]: https://storage.googleapis.com/chrome-supersize/index.html
[milestone size breakdowns]: https://goto.google.com/chrome-supersize
[the viewer]: https://chrome-supersize.firebaseapp.com/viewer.html

### Optimizing Translations (Strings)

Expand Down Expand Up @@ -236,8 +239,6 @@ Practical advice:
* In C++, static objects are created at compile time, but in Java they
are created by executing code within `<clinit>()`. There is often little
advantage to initializing class fields statically vs. upon first use.
* Use `String.format()` instead of concatenation.
* Concatenation causes a lot of StringBuilder code to be generated.
* Try to use default values for fields rather than explicit initialization.
* E.g. Name booleans such that they start as "false".
* E.g. Use integer sentinels that have initial state as 0.
Expand All @@ -248,11 +249,17 @@ Practical advice:
`onFinished(bool)`.
* E.g. rather than have `onTextChanged()`, `onDateChanged()`, ..., have a
single `onChanged()` that assumes everything changed.
* Ensure unused code is optimized away by ProGuard / R8.
* Ensure unused code is optimized away by R8.
* See [here][proguard-build-doc] for more info on how Chrome uses ProGuard.
* Add `@CheckDiscard` to methods or classes that you expect R8 to inline.
* Add `@RemovableInRelease` to force a method to be a no-op when DCHECKs
are disabled.
* See [here][proguard-build-doc] for more info on how Chrome uses ProGuard.
* Use [//third_party/r8/playground][r8-playground] to figure out how various
coding patterns are optimized by R8.
* Build with `enable_proguard_obfuscation = false` and use
`//third_party/android_sdk/public/build-tools/*/dexdump` to see how code was
optimized directly in apk / bundle targets.


[proguard-build-doc]: /build/android/docs/java_optimization.md
[size-trybot]: /tools/binary_size/README.md#Binary-Size-Trybot-android_binary_size
Expand All @@ -261,6 +268,7 @@ Practical advice:
[template_bloat_one]: https://bugs.chromium.org/p/chromium/issues/detail?id=716393
[template_bloat_two]: https://chromium-review.googlesource.com/c/chromium/src/+/2639396
[supersize-console]: /tools/binary_size/README.md#Usage_console
[r8-playground]: /third_party/r8/playground

### Optimizing Third-Party Android Dependencies

Expand Down

0 comments on commit b000be7

Please sign in to comment.