I'm looking at my production builds and 50% of the build time is in the task minifyProductionReleaseWithR8. Looking at Google's guides for optimizing build speed there is nothing mentioned about R8. Generally, I'm working towards breaking out more modules to enable better build parallelization but I don't know if that will affect R8 minification time.
Related
I want both ProGuard and R8 to perform code shrinking and optimization: I'm sure R8 after a year of development cannot be as cool as ProGuard after 15 years.
android.enableR8 flag enables R8 instead of ProGuard.
Is there any way to use both tools using official Android toolchain, i. e. Gradle with Android plug-in?
There is no supported way of running both R8 and ProGuard inside Android Studio. I suggest that you compare the results of the two shrinkers, and decide which one you want to stick with. If you see R8 producing larger output than ProGuard please let us know, by file a bug report using this link.
The new version of Android Studio (3.4) just came out and brings with it default support for R8 instead of Proguard. Could someone explain the key differences between the two and any apparent benefits to using R8?
The history of Android build process kept changing and the developers are constantly trying to make it more efficient concerning build time and generated .dex file sizes. So, throughout the history there has been many variation of the process of generating .dex files from .java files.
Before R8 or D8, the Android build process involved these four steps;
SourceCode(.java) ---javac---> Java Bytecode(.class) ---Proguard---> Optimized Java bytecode(.class) ---Dex---> Dalvik Optimized Bytecode(.dex)
Then, the Android developers decided to merge all the steps in between to 1 step called Jack&Jill for optimization. However, this was introduced in 2015 and abandoned in 2017 due to not being flexible enough to work with all the growing development tools.
Then, D8 was introduced, which is a reverting back to original 4 step build process, with an optimized Dex transform. This implementation produced better quality bytecode than dx, with fewer instructions and better register allocation.
Now to R8, which has a similar goal with Jack&Jill as a starting point, merging two of these build steps into one. The Proguard and Dex step. So, instead of first Proguard processing the .class file returning again .class files and Dex/D8 processor taking in .class and returning .dex files, R8 merges these two steps, and takes in .class files, returning .dex files. This tool is still getting better, trying to optimize the build process even more. So, it is smart to migrate your project to R8 now, as it is a still growing tool which will be the default build tool soon. (As can be seen by enabled by default in the upgrade of Android Studio(3.4))
Also, the developers in Google issue tracker are very fast in returning to the issues reported about R8, as they are hungry for feedback and want to perfect this tool.
It has been reported that using R8 produces smaller .dex files, and does a more efficient minification of removing unused classes. This is a plus and a minus in some way. It is a plus obviously because smaller size is always better(in programming!),it is a minus because you have to intricately go through your code, and detect your entry points and reimplement the keep rules in your proguard file accordingly, as R8 introduces a more aggressive minification than Proguard.
For more information you can look into this article which includes very detailed explanation on R8 vs. Proguard: https://www.guardsquare.com/en/blog/proguard-and-r8
Also, this official speech from Google I/O 2018 : https://www.youtube.com/watch?v=x9T5EYE-QWQ&t=1194s
Hope this helps,
ProGuard vs R8
History flow
ProGuard -> R8
// R8 is default optimizer of .class files from Android Studio v3.4
ProGuard[About] is open source product
R8 is a Google product
Target:
minify, shrinking
optimize
obfuscate, renaming
R8
R8 has better performance because convert .class directly into .dex without extra step (optimised .class)
R8 has better compatibility with Kotlin
I have an Android project with multiple modules where the build time is slow even if I try to rebuild it without changing anything.
Its structure is similar to:
There are more "parent" (and independent parent siblings) and "feature" modules but the setup is that of the picture.
My gradle.propertiesfile is as follows:
org.gradle.jvmargs=-Xmx4096m -Xms2048m
org.gradle.parallel=true
org.gradle.daemon=true
org.gradle.configureondemand=true
And I'm using the Gradle version 3.5 and the plugin version 2.4.0-alpha7.
The project also uses multidex (javaMaxHeapSize "4g" and jumboMode true), data binding, kotlin alongside java, and several annotation processors.
When a build, I can see multiple threads running different tasks in parallel for most of the project, except mostly for the final "app" module (which I assume is normal).
But a lot of time seems to be spent on different
::compileJavaWithJavac tasks. Even without changing anything, build takes about 30 secs on a MacBook Pro i7 with 16 Gb RAM.
If I change one line of code inside a method of a feature module (without even changing the method's signature), the build time goes over 1:30 minutes.
Are these normal times? Is there something I can optimise further to improve build times?
I also checked some of the other answers:
From this one, setting preDexLibraries = false doesn't help and I already use assembleDebug
incremental = true suggested here doesn't work and is deprecated
Disabling instant run seems to help a little but not much
The project's build flavour discussed above already sets minSdkVersion 21
you should make the feature module independent as much you can and any dependency with other module please consider the stub. A kind of the proxy which contain only interface feature1 -> featureonestub->feature2
I don't see any statistics given by facebook on why redex is any better than using proguard. Could anyone list the pros and cons? Apparently, redex is supposed to make Android run faster. There is a poor article http://www.i-programmer.info/news/80-java/9034-facebooks-redex-makes-android-more-efficient.html
How about getting it from the horse's mouth? redex on github
Just in case the link breaks in the future:
How does this compare to ProGuard?
ReDex is conceptually similar to ProGuard, in that both optimize
bytecode. ReDex, however, optimizes .dex bytecode, while ProGuard
optimizes .class bytecode before it is lowered to .dex. Operating on
.dex is sometimes an advantage: you can consider the number of virtual
registers used by a method that is an inlining candidate, and you can
control the layout of classes within a dex file. But ProGuard has many
capabilities that ReDex does not (for example, ReDex will not remove
unused method parameters, which ProGuard does).
In our opinion, comparing ReDex and ProGuard is a bit
apples-and-oranges, since we have focused on optimizations that add
value on top of ProGuard. We use both tools to optimize the Facebook
app. Our reported performance and size improvements (about 25% on both
dex size and cold start time) are based on using ReDex on an app
already optimized with ProGuard. We have no plans to measure
performance without ProGuard.
After running headfirst into as many problems as there are permutations of the set of Android command-line tools, I finally managed to compile a mix of Scala and Java source code into a usable apk.
As many suggest, I used proguard to squeeze the Scala library through the dex tool. The problem is this:
BUILD SUCCESSFUL
Total time: 1 minute 29 seconds
One minute and a half. We're talking about an application with Hello-World complexity here. I don't think I can develop like that. I'm gonna need to take meditation classes.
This is the proguard configuration:
-injars ${out.absolute.dir}/classes:${scala-library.jar}(!META-INF/MANIFEST.MF,!library.properties)
-outjars ${out.absolute.dir}/classes.min.jar
-libraryjars ${android.jar}
-dontwarn
-dontoptimize
-dontobfuscate
-keep public class * extends android.app.Activity
Is there a way to speed up the proguard step?
Edit: I'm running this in a pretty decent dual-core, 3GB ram machine, on top of 64-bit Linux. A run of ant compile (scalac/javac) takes 3 seconds. A full ant install takes 1:30, as described above. It's the proguard step that "freezes", according to the output, most likely because of the scala/android runtime lib sizes.
Working via android Ant builds is probably not the right way to go about this.
The current "best advice" is to use SBT with the
proguard (https://github.com/siasia/xsbt-proguard-plugin) and
android (https://github.com/jberkel/android-plugin)
plugins.
ProGuard takes a lot longer to shrink the Scala 2.9.1 library than the Scala 2.8.1 library (54 seconds vs. 13 seconds, for 8.5 MB vs. 6.2 MB). Either the structure of the library classes has changed fundamentally, or some new classes are causing excessive computations. I'll have to figure out if ProGuard or its configuration can be improved for this case. For now, you might be able to work with Scala 2.8.1.
I'm assuming your ProGuard configuration also contains the required options for Android and for Scala, as discussed in the ProGuard manual. If you are using the regular Android build process, the input (classes, libs) and libraries (android.jar) are already specified for you in the Ant build file, and you don't need to specify them again in the ProGuard configuration file. Reading them twice will just take time and generate many warnings (which you have switched off completely -- it's safer to switch them off selectively).
If you have a rooted phone and only want to test on this you can install the scala libs directly on your phone so you don't need the proguard step anymore:
https://github.com/jrudolph/scala-android-libs