Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Codegen

You’ve been working on a large Rust project and notice that your development builds are taking longer and longer. While you don’t mind waiting a bit for release builds since they need to be optimized, the slow compilation during development is really hurting your productivity. You wonder if there’s a way to get faster builds during development, even if it means sacrificing some runtime performance for your debug binaries.

Rust is built on top of the LLVM compiler, which means it can make use of the optimizations and the wide range of backends. This is a good thing, Rust would not be able to support as many targets as it does without the LLVM underpinnings of its code generation.

However, LLVM is a rather heavy dependency. It is designed to produce fast binaries, not to produce binaries fast. This is a good property when building release binaries, however when you are actively developing on a project, you tend to care about a fast iteration loop more than getting the best performance out of your binaries (which, in this case, will mostly be unit tests).

Therefore, there is an advantage in switching to a different codegen backend during development (non-release builds), if that leads to faster iterations.

Cranelift

Cranelift started out as a library to help in implementing the JIT-based WebAssembly runtime wasmtime. However, due to the way in which it was built, it can be used in more than just this application. The Rust compiler team has adopted it as an alternative codegen backend, in addition to LLVM. Since it is relatively young, it is not as mature as LLVM. It does have some properties that make it very appealing in certain scenarios: because it focusses on generating binaries quickly, it tends to be faster than LLVM. This makes it useful for building in development code, where a fast iteration time is more important than good runtime performance.

In my testing, I was able to get around a 30% speedup by using the cranelift backend instead of the default LLVM backend, but your mileage may vary.

https://github.com/rust-lang/rustc_codegen_cranelift

Example

Install the Cranelift codegen for the Rust compiler using:

rustup component add rustc-codegen-cranelift-preview --toolchain nightly

Then compile using:

CARGO_PROFILE_DEV_CODEGEN_BACKEND=cranelift cargo +nightly build -Zcodegen-backend

Note that Cranelift is only available on nightly Rust, so you’ll need to use a nightly toolchain for development builds if you want to take advantage of this optimization.

Using Cranelift makes builds roughly 30% faster than using LLVM.

CrateLLVMCraneliftSpeedup
ripgrep7.50s5.72s30%

Reading

Daroc announces the availability of the Cranelift compiler backend for Rust. He explains the history behind the Cranelift project, having been developed for the Wasmtime runtime, and that it can generate code faster than the LLVM project, at the expense of doing less optimizations.