Mill Build Tool Engineering Blog

Welcome to the Mill development blog! This page contains posts and articles on technical topics related to the development of the Mill build tool. These discuss topics related to JVM languages and monorepo build tooling.

Why Use a Monorepo Build Tool?

Li Haoyi, 17 December 2024

Software build tools mostly fall into two categories:

  1. Single-language build tools, e.g. Maven (Java), Poetry (Python), Cargo (Rust)

  2. Monorepo build tools targeting large codebases, e.g. Bazel, Pants, Buck, and Mill

One question that comes up constantly is why do people use Monorepo build tools? Tools like Bazel are orders of magnitude more complicated and hard to use than tools like Poetry or Cargo, so why do people use them at all? Are they stupid?

It turns out that Monorepo build tools like Bazel or Mill do a lot of non-obvious things that other build tools don’t, that become important in larger codebases (100-10,000 active developers). These features are generally irrelevant for smaller projects, which explains why most people do not miss them. But past a certain size of codebase and engineering organization these features become critical. We’ll explore some of the core features of "Monorepo Build Tools" below, from the perspective of Bazel (which I am familiar with) and Mill (which this technical blog is about).

How Fast Does Java Compile?

Li Haoyi, 29 November 2024

Java compiles have the reputation for being slow, but that reputation does not match today’s reality. Nowadays the Java compiler can compile "typical" Java code at over 100,000 lines a second on a single core. That means that even a million line project should take more than 10s to compile in a single-threaded fashion, and should be even faster in the presence of parallelism

Doing some ad-hoc benchmarks, we find that although the compiler is blazing fast, all build tools add significant overhead over compiling Java directly:

Mockito Core

Time

Compiler lines/s

Slowdown

Netty Common

Time

Compiler lines/s

Slowdown

Javac Hot

0.36s

115,600

1.0x

Javac Hot

0.29s

102,500

1.0x

Javac Cold

1.29s

32,200

4.4x

Javac Cold

1.62s

18,300

5.6x

Mill

1.20s

34,700

4.1x

Mill

1.11s

26,800

3.8x

Gradle

4.41s

9,400

15.2x

Maven

4.89s

6,100

16.9x

Although Mill does the best in these benchmarks among the build tools (Maven, Gradle, and Mill), all build tools fall short of how fast compiling Java should be. This post explores how these numbers were arrived at, and what that means in un-tapped potential for Java build tooling to become truly great.