Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle vs Bazel performance of builds

So everyone is talking about bazel now, but migration to it isn't automated (gradle is better in this regard when migrating from maven). So I don't want to invest time into manually converting any repository to it.

But I can't find any information about build speed difference between recent versions of gradle (5.6 >) and bazel (1.0).

Can anyone share a link or his own experience? I'm mostly interested in incremental builds where just a couple of files have changed.

like image 488
user1685095 Avatar asked Nov 01 '19 21:11

user1685095


People also ask

Is Bazel better than Maven?

Bazel supports multiple build files and multiple targets per BUILD file, allowing for builds that are more incremental than Maven's. Maven takes charge of steps for the deployment process. Bazel does not automate deployment. Bazel enables you to express dependencies between languages.

Why is Bazel fast?

Bazel may give you faster build times because it can recompile only the files that need to be recompiled. Similarly, it can skip re-running tests that it knows haven't changed. Bazel produces deterministic results. This eliminates skew between incremental and clean builds, laptop and CI system, etc.

Is Gradle faster?

GraalVM JavaScript Is Faster Than NashornAnd six times faster than Nashorn Enterprise Edition. (As measured by the Octane JavaScript Benchmark Suite). The top developers in the GraalVM team are very focused on the performance of all supported programming languages. They track performance improvements in every release.

Why is Gradle faster?

The benefit of forking is that the memory-intensive compilation happens in a different process, leading to much less garbage collection in the main Gradle daemon. Less garbage collection in the daemon means that Gradle's infrastructure can run faster, especially if you are also using --parallel .


2 Answers

Dropbox ran some benchmarks recently:

enter image description here

Note that the clean build without a cache scenario is significantly slower for Bazel, whereas the incremental build scenario is significantly faster.

Bazel build units tend to have a smaller granularity than Gradle's. It's common to see java_library targets with just a single source file. The command line actions in these build units, also known as targets, are individually cached (locally or remotely) and composed together to build a java_binary.

With many small build units, there are typically more actions to execute, and therefore more disk I/O and computation, leading to a slower initial, clean build time.

Some executables of these actions may also have a high startup cost (e.g javac), which adds up when these processes are restarted many times. Bazel has a mechanism called persistent workers, where the executable process for individual actions (e.g. a compiler wrapper for javac, tsc, scalac or ghc) can be persisted across action executions, saving on startup times and enabling an even lower level of caching at the process level.

On the other hand, Bazel's small build units enable highly incremental builds and fast iterative development, as seen in the chart above.

The small build units also enable Bazel to form a dependency graph with a high degree of parallelism. With remote execution, you can run 100s and 1000s of small build actions in parallel.

The dependency graph is also highly optimized for the no-op build case. If nothing has changed in your project, Bazel should take as little time as possible to figure out nothing has changed, so nothing needs to be done.

The drawback of a slow clean build can also be mitigated with remote caches, remote execution, or not running the relatively rare bazel clean since builds aim to be hermetic, deterministic, and consistent. A build with 100% remote cache hits are common with Bazel.

like image 129
Jin Avatar answered Oct 06 '22 01:10

Jin


Okay, I've migrated closed source project containing ~100_000 loc of java to bazel.

Gradle 5.6.3 vs bazel 1.0.1

As I've said my interest is about developer productivity and hence about incremental builds.

I've used the following in BUILD for bazel so I haven't used most granular approach because I don't think it's really maintainable and that anybody except big companies with a lot of devops could use that. And in any case I see the fact that I would need to do this manually to improve build speed as a downside of bazel.

java_binary(
    srcs = glob(["src/main/java/**/*.java"]),
    resources = glob(["src/main/resources/**"]),
    ...
)

Incremental build with one or two changed files.

gradle - 1s, bazel - 4.227s

I've tried that multiple times and each time gradle was significatly faster. I Haven't tested incremental build when more than one or two files have been changed, maybe in that scenario bazel would be the same or faster than gradle.

No op build gradle - 700ms, bazel - 0.090ms

So speed-wise gradle seems to be the winner for developer productivity. Bazel have more safe defaults (error-prone is on by default) in gradle you have to enable it yourself, but IMHO the flexibility of gradle outweighs more safe defaults of bazel.

like image 42
user1685095 Avatar answered Oct 06 '22 00:10

user1685095