Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Many small modules, or few large modules for best build performance?

A few years ago, when first adopting gradle for Android (before Gradle 2.0), I found that there was some overhead to using and depending upon a module, so I've stayed away from splitting my project into smaller modules, and instead have created very large modules. After trying out some other build systems (like Buck for instance), performance is gained by splitting your code into multiple small modules. Some of the modern programming languages like Kotlin even have visibility modifiers specifically built around the concept of splitting your code into modules.

We're currently at Gradle 2.14.1 (almost 3.0), and for the past several releases, they've quoted massive performance gains. With the changes to Gradle / the Android plugin the past few years, does it now produce faster builds to split your code into smaller modules, or to use fewer large modules?

like image 420
spierce7 Avatar asked Aug 20 '16 23:08

spierce7


1 Answers

Both for Gradle and for Kotlin there have been large recent gains in compilation performance for an overall build. Including lowering the overhead of multiple modules in a build.

You can see some examples of these increases in this recent article: Kotlin vs. Java Compilation Speeds

The overhead between multiple modules is reduced by a combination of Gradle's configuration step for modules being order of magnitudes faster, and by keeping more in memory so that it does not have to be reloaded on each compilation run, and not compiling things that fine-grained dependency checking considers not needing to be recompiled.

Here are tips:

  • make sure Gradle daemon is enabled (is by default now, so unless you turned it off, all good)
  • upgrade to Kotlin 1.0.3 (and keep an eye out for 1.0.4 release soon)
  • enable incremental Kotlin compilation:

    To enable incremental compilation for Gradle, you need to set the kotlin.incremental property to true (for example, by adding the line kotlin.incremental=true to the gradle.properties file in the root directory of your project).

  • use Android studio 2.1 or newer and enable DEX in Process

    Android Studio 2.1 enables a new feature: Dex In Process, that can dramatically increase the speed of full clean builds as well as improving Instant Run performance.

  • be sure that any tasks you use support incremental running in Gradle, some don't and can slow down your build times (for example Dokka task runs no matter what changed), you can disable tasks that you don't need all the time using -x<task> parameter to Gradle.

Now whether it is faster for multi-module builds or single module builds, I find now that the overhead of modules that haven't changed is negligible. And for those that have, is the normal cost of compilation.

Beware that incremental compilation doesn't always work between Android builds in Gradle due to Android plugin for Gradle changing the classpath ordering between builds. Although this tends to be consistent between builds there is a chance that if it recalculates the classpath it will be a different order and cause a new full build. But this would be a problem whether you are single or multiple module building.

Overall answers to your question probably differ radically across projects, hardware, different configurations, and people's perceptions and even misuse and misconfiguration of builds. Given the improvements mentioned above you have to decide to take the time to test the current state for your actual project -- and see for yourself!

like image 147
Jayson Minard Avatar answered Oct 07 '22 14:10

Jayson Minard