| The optimization step of ProGuard can be switched off with the |
| [`-dontoptimize`](usage.md#dontoptimize) option. For more fine-grained |
| control over individual optimizations, experts can use the |
| [`-optimizations`](usage.md#optimizations) option, with a filter based |
| on the optimization names listed below. The filter works like any |
| [filter](usage.md#filters) in ProGuard. |
| |
| The following wildcards are supported: |
| |
| | | |
| |-----|------------------------------------------------------- |
| | `?` | matches any single character in an optimization name. |
| | `*` | matches any part of an optimization name. |
| |
| An optimization that is preceded by an exclamation mark '**!**' is |
| *excluded* from further attempts to match with *subsequent* optimization |
| names in the filter. Make sure to specify filters correctly, since they |
| are not checked for potential typos. |
| |
| For example, |
| "**`code/simplification/variable,code/simplification/arithmetic`**" only |
| performs the two specified peephole optimizations. |
| |
| For example, "`!method/propagation/*`" performs all optimizations, |
| except the ones that propagate values between methods. |
| |
| For example, "`!code/simplification/advanced,code/simplification/*`" |
| only performs all peephole optimizations. |
| |
| Some optimizations necessarily imply other optimizations. These are then |
| indicated. Note that the list is likely to change for newer versions, as |
| optimizations are added and reorganized. |
| |
| `library/gson` |
| : Optimizes usages of the Gson library, whenever possible. See [Gson |
| optimization](optimizations.md#gson) for more details. |
| |
| `class/marking/final` |
| : Marks classes as final, whenever possible. |
| |
| `class/unboxing/enum` |
| : Simplifies enum types to integer constants, whenever possible. |
| |
| `class/merging/vertical` |
| : Merges classes vertically in the class hierarchy, whenever possible. |
| |
| `class/merging/horizontal` |
| : Merges classes horizontally in the class hierarchy, whenever possible. |
| |
| `class/merging/wrapper` |
| : Merges wrapper classes with their wrapped classes, whenever possible. |
| |
| `field/removal/writeonly`<div>(⇒ `code/removal/advanced`)</div> |
| : Removes write-only fields. |
| |
| `field/marking/private` |
| : Marks fields as private, whenever possible. |
| |
| `field/propagation/value`<div>(⇒ `code/simplification/advanced`)</div> |
| : Propagates the values of fields across methods. |
| |
| `method/marking/private` |
| : Marks methods as private, whenever possible (*devirtualization*). |
| |
| `method/marking/static`<div>(⇒ `code/removal/advanced`)</div> |
| : Marks methods as static, whenever possible (*devirtualization*). |
| |
| `method/marking/final` |
| : Marks methods as final, whenever possible. |
| |
| `method/marking/synchronized` |
| : Unmarks methods as synchronized, whenever possible. |
| |
| `method/removal/parameter`<div>(⇒ `code/removal/advanced`)</div> |
| : Removes unused method parameters. |
| |
| `method/propagation/parameter`<div>(⇒ `code/simplification/advanced`)</div> |
| : Propagates the values of method parameters from method invocations to the |
| invoked methods. |
| |
| `method/propagation/returnvalue`<div>(⇒ `code/simplification/advanced`)</div> |
| : Propagates the values of method return values from methods to their |
| invocations. |
| |
| `method/inlining/short` |
| : Inlines short methods. |
| |
| `method/inlining/unique` |
| : Inlines methods that are only called once. |
| |
| `method/inlining/tailrecursion` |
| : Simplifies tail recursion calls, whenever possible. |
| |
| `code/merging` |
| : Merges identical blocks of code by modifying branch targets. |
| |
| `code/simplification/variable` |
| : Performs peephole optimizations for variable loading and storing. |
| |
| `code/simplification/arithmetic` |
| : Performs peephole optimizations for arithmetic instructions. |
| |
| `code/simplification/cast` |
| : Performs peephole optimizations for casting operations. |
| |
| `code/simplification/field` |
| : Performs peephole optimizations for field loading and storing. |
| |
| `code/simplification/branch`<div>(⇒ `code/removal/simple`)</div> |
| : Performs peephole optimizations for branch instructions. |
| |
| `code/simplification/object` |
| : Performs peephole optimizations for object instantiation. |
| |
| `code/simplification/string` |
| : Performs peephole optimizations for constant strings. |
| |
| `code/simplification/math` |
| : Performs peephole optimizations for Math method calls. |
| |
| `code/simplification/advanced`<div>(*best used with* `code/removal/advanced`)</div> |
| : Simplifies code based on control flow analysis and data flow analysis. |
| |
| `code/removal/advanced`<div>(⇒ `code/removal/exception`)</div> |
| : Removes dead code based on control flow analysis and data flow analysis. |
| |
| `code/removal/simple`<div>(⇒ `code/removal/exception`)</div> |
| : Removes dead code based on a simple control flow analysis. |
| |
| `code/removal/variable` |
| : Removes unused variables from the local variable frame. |
| |
| `code/removal/exception` |
| : Removes exceptions with empty try blocks. |
| |
| `code/allocation/variable` |
| : Optimizes variable allocation on the local variable frame. |
| |
| ProGuard also provides some unofficial settings to control |
| optimizations, that may disappear in future versions. These are Java |
| system properties, which can be set as JVM arguments (with `-D...`): |
| |
| `maximum.inlined.code.length` (default = 8 bytes) |
| : Specifies the maximum code length (expressed in bytes) of short methods |
| that are eligible to be inlined. Inlining methods that are too long may |
| unnecessarily inflate the code size. |
| |
| `maximum.resulting.code.length` (default = 8000 bytes for JSE, 2000 bytes for JME) |
| : Specifies the maximum resulting code length (expressed in bytes) allowed |
| when inlining methods. Many Java virtual machines do not apply just-in-time |
| compilation to methods that are too long, so it's important not to let them |
| grow too large. |
| |
| `optimize.conservatively` (default = unset) |
| : Allows input code with ordinary instructions intentionally throwing |
| **`NullPointerException`**, `ArrayIndexOutOfBoundsException`, or |
| **`ClassCastException`**, without any other useful purposes. By default, |
| ProGuard may just discard such seemingly useless instructions, |
| resulting in better optimization of most common code. |
| |
| ## Gson optimization {: #gson} |
| |
| ProGuard optimizes Gson code by detecting which domain classes are serialized |
| using the Gson library. It replaces the reflection-based implementation of |
| GSON for reading and writing fields with injected and optimized code that |
| accesses the fields of the domain classes directly when reading and writing |
| JSON. The benefits of this optimization are the following: |
| |
| - Domain classes used in conjunction with GSON can be freely obfuscated. |
| - The injected serialization code gives better performance compared to the |
| GSON implementation, which relies on reflection. |
| - Less configuration is needed as the optimization automatically keeps classes |
| and fields that are required for serialization. |
| |
| ### Configuration |
| |
| The Gson optimization is enabled by default and doesn't require any additional |
| configuration, as long as the application code doesn't use unsupported Gson |
| features(see [Known limitations](optimizations.md#gsonlimitations)). |
| |
| ### Known limitations {: #gsonlimitations} |
| |
| ProGuard can not optimize the following use cases of Gson: |
| |
| - Serializing classes containing one of the following Gson annotations: |
| - `@JsonAdapter` |
| - `@Since` |
| - `@Until` |
| - Serializing classes that have generic type variables in their signature. |
| - Serializing classes using a Gson instance that was built with one of the |
| following settings on the GsonBuilder: |
| - `excludeFieldsWithModifier` |
| - `setFieldNamingPolicy` |
| |
| When one of the above Gson features is used, ProGuard automatically preserves |
| the original Gson implementation for all affected domain classes. |
| |
| This means that the serialized fields of these domain classes need to be |
| explicitely kept again in the DexGuard configuration so that they can be |
| safely accessed through reflection. |