<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Performance on Kron&#39;s</title>
    <link>/blog/tags/performance/</link>
    <description>Recent content in Performance on Kron&#39;s</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <copyright>Blog Owner (CC BY 4.0)</copyright>
    <lastBuildDate>Sun, 21 Dec 2025 12:00:00 +0000</lastBuildDate>
    <atom:link href="/blog/tags/performance/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Speeding Up Rust Compilation</title>
      <link>/blog/posts/speeding-up-rust-compilation/</link>
      <pubDate>Sun, 21 Dec 2025 12:00:00 +0000</pubDate>
      <guid>/blog/posts/speeding-up-rust-compilation/</guid>
      <description>Rust compile times are slow. Here&#39;s why and what you can do about it.&#xA;The Problem Rust compilation has two bottlenecks:&#xA;Frontend (rustc): parsing, macro expansion, type checking, borrow checking Backend (LLVM): optimization, code generation If cargo check is slow, your bottleneck is the frontend. If cargo check is fast but cargo build is slow, it&#39;s the backend.&#xA;Backend Fixes Cranelift Cranelift is an alternative code generator built for the Wasmtime WebAssembly runtime.</description>
      <content:encoded><![CDATA[<p>Rust compile times are slow. Here's why and what you can do about it.</p>
<h2 id="the-problem">The Problem</h2>
<p>Rust compilation has two bottlenecks:</p>
<ol>
<li><strong>Frontend</strong> (rustc): parsing, macro expansion, type checking, borrow checking</li>
<li><strong>Backend</strong> (LLVM): optimization, code generation</li>
</ol>
<p>If <code>cargo check</code> is slow, your bottleneck is the frontend. If <code>cargo check</code> is
fast but <code>cargo build</code> is slow, it's the backend.</p>
<h2 id="backend-fixes">Backend Fixes</h2>
<h3 id="cranelift">Cranelift</h3>
<p>Cranelift is an alternative code generator built for the Wasmtime WebAssembly
runtime. It prioritizes compile speed over output quality - perfect for dev
builds.</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">rustup component add rustc-codegen-cranelift-preview
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nv">CARGO_PROFILE_DEV_CODEGEN_BACKEND</span><span class="o">=</span>cranelift cargo build</span></span></code></pre></div><p>Expect ~2x faster codegen with slower runtime performance.</p>
<h3 id="mold-linker">mold Linker</h3>
<p>The default linker is slow. mold is a drop-in replacement optimized for speed.</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sudo apt install mold clang</span></span></code></pre></div>




<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># .cargo/config.toml</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="p">[</span><span class="nx">target</span><span class="p">.</span><span class="nx">x86_64-unknown-linux-gnu</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nx">linker</span> <span class="p">=</span> <span class="s2">&#34;clang&#34;</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="nx">rustflags</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;-C&#34;</span><span class="p">,</span> <span class="s2">&#34;link-arg=-fuse-ld=mold&#34;</span><span class="p">]</span></span></span></code></pre></div><p>Linking goes 2-5x faster.</p>
<h3 id="sccache">sccache</h3>
<p>Caches compiler outputs. Helps with rebuilds and CI.</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">cargo install sccache</span></span></code></pre></div>




<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># .cargo/config.toml</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="p">[</span><span class="nx">build</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nx">rustc-wrapper</span> <span class="p">=</span> <span class="s2">&#34;sccache&#34;</span></span></span></code></pre></div><p>The cache lives on disk by default. The OS page cache keeps hot entries in RAM
automatically - no need for tmpfs unless you're seeing disk I/O bottlenecks.</p>
<h3 id="aggressive-dev-profile">Aggressive Dev Profile</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c"># Cargo.toml</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="p">[</span><span class="nx">profile</span><span class="p">.</span><span class="nx">dev</span><span class="p">]</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="nx">opt-level</span> <span class="p">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="nx">debug</span> <span class="p">=</span> <span class="kc">false</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="nx">codegen-units</span> <span class="p">=</span> <span class="mi">256</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="nx">incremental</span> <span class="p">=</span> <span class="kc">true</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="p">[</span><span class="nx">profile</span><span class="p">.</span><span class="nx">dev</span><span class="p">.</span><span class="nx">package</span><span class="p">.</span><span class="s2">&#34;*&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="nx">opt-level</span> <span class="p">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="nx">codegen-units</span> <span class="p">=</span> <span class="mi">256</span></span></span></code></pre></div><p>More codegen units = more parallelism = faster builds (but worse code).</p>
<h2 id="frontend-fixes">Frontend Fixes</h2>
<p>Bad news: there's no quick fix for frontend speed.</p>
<p>The Rust compiler team is working on parallel frontend compilation, but it's
years away from matching Go's speed. The borrow checker, complex generics, and
procedural macros all take time.</p>
<p>What helps:</p>
<ul>
<li>Fewer dependencies (less to parse)</li>
<li>Fewer proc macros (serde, tokio macros are expensive)</li>
<li>Smaller crates (better parallelism)</li>
<li><code>cargo check</code> instead of <code>cargo build</code> when possible</li>
</ul>
<h2 id="why-go-is-faster">Why Go is Faster</h2>
<p>Go was designed from day one for fast compilation:</p>
<ul>
<li>Simple grammar (no lifetimes, no generics originally)</li>
<li>File-level parallelism (not crate-level)</li>
<li>Custom compiler built for speed (not LLVM)</li>
<li>No borrow checker</li>
</ul>
<p>Rust chose safety and zero-cost abstractions over compile speed. That's a
fundamental design tradeoff, not a bug to fix.</p>
<h2 id="complete-setup">Complete Setup</h2>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c"># Cargo.toml</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="p">[</span><span class="nx">profile</span><span class="p">.</span><span class="nx">dev</span><span class="p">]</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="nx">opt-level</span> <span class="p">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="nx">debug</span> <span class="p">=</span> <span class="kc">false</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="nx">codegen-units</span> <span class="p">=</span> <span class="mi">256</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="nx">incremental</span> <span class="p">=</span> <span class="kc">true</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="p">[</span><span class="nx">profile</span><span class="p">.</span><span class="nx">dev</span><span class="p">.</span><span class="nx">package</span><span class="p">.</span><span class="s2">&#34;*&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="nx">opt-level</span> <span class="p">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="nx">codegen-units</span> <span class="p">=</span> <span class="mi">256</span></span></span></code></pre></div>




<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># .cargo/config.toml</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="p">[</span><span class="nx">target</span><span class="p">.</span><span class="nx">x86_64-unknown-linux-gnu</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nx">linker</span> <span class="p">=</span> <span class="s2">&#34;clang&#34;</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="nx">rustflags</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;-C&#34;</span><span class="p">,</span> <span class="s2">&#34;link-arg=-fuse-ld=mold&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="p">[</span><span class="nx">build</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="nx">rustc-wrapper</span> <span class="p">=</span> <span class="s2">&#34;sccache&#34;</span></span></span></code></pre></div>




<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># Install tools</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">sudo apt install mold clang
</span></span><span class="line"><span class="ln">3</span><span class="cl">cargo install sccache
</span></span><span class="line"><span class="ln">4</span><span class="cl">rustup component add rustc-codegen-cranelift-preview</span></span></code></pre></div><h2 id="reality-check">Reality Check</h2>
<p>Even with all optimizations, Rust won't match Go's compile speed. But you can
get 2-4x faster dev builds, which makes iteration less painful.</p>
<p>Ship with LLVM. Iterate with cranelift + sccache + mold.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
