
2026/11/12 6:20
弛緩:Rust のビルド時間を短縮するための JIT コンパイラ
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Summary:
Relax は、
rustc、LLVM、またはリンカーを必要とせずにコードを瞬時にコンパイルするライブコンパイラー兼 JIT ランタイムとして機能する画期的な Rust ツールです。実行時に関数をオンデマンドでコンパイルすることでホットパスの最適化を行い、アプリケーションの状態を維持し、ライブエディットのための高速イテレーションおよび「ホットパッチング」を可能にします。Apple M4 ハードウェア上では、Relax は起動時に劇的な速度向上を示しており、大型 3D ゲームは rustc の約 3 分に対してわずか 11 秒で起動し、小規模なアプリケーションは標準 Rust コンパイルの 3.7 秒に対して 0.24 秒です。そのピークパフォーマンスは完全最適化された rustc ビルドよりもわずかに低いですが(アーキテクチャによって 12~24% 遅い)、冷たい起動およびライブエディティングワークフローにおいて大きな利点を提供します。現在 x86-64 および AArch64 をサポートしており、Relax はコンパイラーとアプリケーション間でメモリを共有しますが、構造体レイアウトの変更やインポートの更新など複雑な変更には、relax inspect によるセッションの再起動が必要です。Makepad のような主要プロジェクトは、UI アプリをネイティブビルドなしで実行するために Relax を使用し、時間短縮と AI エージェントのコスト削減を実現しています。アーキテクチャは並行して更新される独立したクライトを採用しており、スタックトレースを保持したままパニックを一時停止する高度なデバッグ機能もサポートしています。本文
Relax: 待つことなしの Rust ライブコンパイラ
Relax は Rust で実装されたライブコンパイラ(Live Compiler)および JIT(即時実行可能コード生成)ランタイムです。プログラムのビルドと実行を同時期に行います。 従来の
rustc が起動前に全ビルドを完了させるのに対し、Relax は各関数が初めて呼ばれる際にコンパイルを開始し、プログラム実行中にホットな関数を最適化しながら、エディタでの編集をプロセスに瞬時に適用(ライブパッチ)します。
主要機能比較:Relax vs cargo + rustc
cargo + rustc| 機能項目 | cargo + rustc | Relax |
|---|---|---|
| 大規模 3D ゲームの性能 | 初回フレーム:ビルドに約 3 分かかる、その後起動。 2 回目実行(M4 MacBook):1.15 秒。 | 初回フレーム:11 秒で M4 MacBook からソース直出しですぐ開始。 |
| 小規模アプリ(コールド/ウォーム) | コールド:3.7 秒、ウォーム:0.41 秒。 | コールド:3.7 秒、ウォーム:0.41 秒。 |
| 編集して実行 | 再ビルド・再リンク・再起動が必要:状態が失われる。 | パッチ適用により、状態は維持される。 |
| 保存時のテスト実行 | テストを再実行(92 つのテストで約 2.2 秒)。 | テストはウォームなまま維持され、変更された関数だけを再実行する。 |
| 型チェック | :全てをチェックしてから実行。貸借関係チェックも同然。 | :各関数を実行前に型チェックし、貸借関係チェックをバックグラウンドで実行。 |
| コード速度(ベースライン) | x64: 1.00× arm64: 基準値。 | x64: 1.12×、arm64: 1.24×(21 のワークロードの幾何平均)。 注:Relax は全体として より遅い傾向にあるが、開発効率向上は圧倒的。 |
| 依存関係 | 、LLVM、リンカーが必要。 | Rust ライブラリ 1 つのみ(438k 行)。crates.io の外部依存関係なし。 |
コード生成のサポート
- x86-64 と AArch64 をサポートします。
- Linux x86-64 および macOS arm64 でクローンしたまま構築可能です。
- 注意:Windows 版は現時点でテストされていません。
トレードオフと制限事項
Relax はリリースビルドではなく、**「編集・実行のループ」**のために設計されています。出荷用ビルドとは別に、開発におけるユニークな機能を提供するためにわずかな性能コストを払う必要があります。
1. コード速度
全体として、
relax が実行するコードは rustc --release よりも遅いです(幾何平均で x64 1.12 倍、arm64 1.24 倍)。LLVM が苦手とする特定の少数のワークロードでは速い場合があります。
2. メモリ使用量の増加
コンパイラ、キャッシュ、および発行されたすべてのコードバージョンがプロセスと共有されます。JIT コードは追加専用(append-only)です。
- コードキャッシュ: シンプルな
アプリでもhello
に 120〜190 MB を使用します。target/relax - 状況確認:
relax inspect <pid> memory
3. 制限事項
: 大規模パッケージではコールドチェックに時間がかかり、メモリ消費も多くなります(改善中)。relax check- クレートサポート: 全てのクレートが動作するわけではありません。
を参照してください。libs/relax/KNOWN_GAPS.md - ライブパッチングの制約: 構造体のレイアウト、インポート、トレイト実装、マクロの変更には再起動が必要です(
)。relax inspect <pid> session relaunch - 貸借関係チェック: 実行中のプログラムと競合しないよう設計されています。
JIT インスペクション機能
relax run を実行すると relax-remote: pid <pid> が出力され、この PID で relax inspect を使用してプロセスを制御します。
| 機能 | コマンド例 |
|---|---|
| ホットパッチング | ファイルを保存すると変更された関数が即座に再コンパイル・入れ替わります。 |
| 保存時のテスト実行 | テストはウォームなまま維持され、変更箇所のみの再実行が可能です。 |
| パニック時の一時停止 | , スレッドを待ち状態にし、ローカル変数参照やコード評価が可能になります(最大 10 分)。 |
| ブレークポイント | , スタック情報を維持しつつ実行を一時停止できます。デバッガー不要です。 |
| ハングアップの診断 | デッドロックやブロッキングの原因を表示します。 |
| プロファイリング | , JIT フレームとネイティブフレームをサンプリングし、呼び出しツリーを確認できます。 |
| フライトレコーダー | パニックや遅延時にイベント履歴を保存します。 |
| メモリ・リーク解析 | RSS やmallocの状態、ヒープ追跡(Linux x64 / macOS arm64 限定)を表示。 |
高度なコマンド(詳細は relax inspect <pid> help
)
relax inspect <pid> help
:asm <fn> vs=rustc
との比較用マシンコード。rustc
: 関数の正確な呼び出し回数。count <fn>- ハードウェアカウンターの監視。
インストールと使用方法
Relax をクローンし、新しいパッケージを JIT で実行しましょう。
# Relax のビルド git clone https://github.com/makepad/relax cd relax cargo build --release --manifest-path relax/Cargo.toml -p relax-runner --bin relax # 作成するプロジェクトのディレクトリ移動 cargo new hello cd hello # JIT モードでの実行(静かなモード) ../relax/target/release/relax run --quiet hello # テストの実行 ../relax/target/release/relax test hello # 型チェックのみ ../relax/target/release/relax check hello
重要:
- パッケージのフォルダ内で動作するため、
フォルダの場所は変更しないでください。relax - 各新しいパッケージはコールド状態から始まります(
でコンパイル済みアートを削除します)。relax clean
ネットワーク設定
- オフラインモード:
またはRELAX_OFFLINE=1
を設定すると、依存関係のダウンロードを無効にできます。CARGO_NET_OFFLINE - Git リポジトリ:
により、リポジトリを単一ファイルとしてローカルに保存可能です。relax fetch <git-url>
新しいツールチェーンの構成
Relax はラッパーや LLVM プラグインではなく、一つの Rust ライブラリとして実装されています。以下の要素を統合・置換しています。
| 段階 | 通常のツール () | Relax |
|---|---|---|
| 文字列処理/展開 | | , |
| 解決/型付け | | |
| 最適化 | + LLVM | (O1, O3) |
| コード生成/リンク | LLVM コードジェネレータ + リンカー | -> 実行可能メモリへの書き込み |
| マニフェスト | Cargo | |
| コア/Std ビルド | プリビルト配布 | Relax がソースからコンパイル (134k 行) |
コンパイル戦略の違い
- 適応型最適化: クレート全体を事前にコンパイルするのではなく、初めて呼ばれる時に一つ関数ずつコンパイルします。ホットな関数はバックグラウンドで O1 → O3 と移動します。
/#[relax(O2)]
属性は即座に高い最適化レベルを適用できます。#[relax(O3)] - キャッシュ: 入力ハッシュをキーとするため、
の必要がない安定したキャッシュ構造です(旧アートを削除しない)。cargo clean - マクロ: ネイティブ
または JIT で実行されます。dylib - ネイティブ API: 外部リソース(GPU, OS)へのアクセスは
を介して行われます。#[relax_api]
Makepad における運用
Makepad は UI アプリで、Relax をランナーとして使用します。
特徴
- 即座の起動: ネイティブビルド不要。ウィンドウがすぐに開き、ビルドはバックグラウンドで進行します。
- 状態維持: 編集を保存し、アプリにパッチ適用されます。
- スマートな再起動: パッチ適用不可な場合(構造変更など)は「更新準備中」と表示され、クリックすると同じプロセス内で再起動し、可能な限り状態を保持します。
- エラー・パニックハンドリング: エラーやクラッシュ時は UI 上でファイル情報付きで表示され、ソース修正後すぐに再開可能です。
- 詳細調査:
,ui find
,versions
,remarks
など、コマンドライン経由でも詳細な情報を取得できます。rec save
性能(Makepad で)
エージェントによる一日の運用において、編集がアプリに到達するまでにかかる時間は中央値 3.6 秒 です(コールドキャッシュでの p90 は 86 秒)。
AI エージェント向け最適化
AI エージェントはビルド時間やトークンコストが高くつきがちです。
Relax + devhub を使用することで以下のメリットがあります。
| メトリック | cargo + rustc | Relax + devhub |
|---|---|---|
| 編集到達 | 大規模アプリで数分かかる(再ビルド・再リンク) | 0.1 秒でパッチ適用(中央値 3.6 秒)。 |
| テスト判定 | 全テストの再実行(2.2 秒程度) | テストをウォームに保ち、変更分のみ実行。 |
| UI 確認 | 再起動・ナビゲーション必要 | ライブアプリから PNG を瞬時に取得。 |
| ワーカー起動 | コールドビルド | ウォーム起動(キャッシュ維持)。 |
実際に運用では 9 つのエージェントが並行動作しており、
devhub は時間あたり 300 以上のジョブを処理しています。
速度比較:Relax vs Rustc(ワークロード別)
定常状態のコードは
LLVM (rustc) よりも遅い傾向にあります(1.00× = rustc ストック)。以下の表は時間の倍率を示します(下数ほど高速)。
| ワークロード | x64 vs ストック | arm64 vs ストック |
|---|---|---|
| テキストシェイピング/グリフレンダリング | 1.36× | 1.33× |
| サイン距離フィールド生成 | 1.31× | 1.26× |
| DEFLATE デコード | 1.20× | 1.26× |
| PNG/Brotli デコード | 1.21× / 1.29× | 1.32× / 1.27× |
| ベクター地図タイルデコード | 1.06× | 1.01× |
| LLM デコード | 1.12× | 1.05× |
| マークダウン解析 | 1.39× | 1.54× |
| HTML 解析 | 1.06× | 1.04× |
| ゲームオーディオミキサー | 1.03× | 1.17× |
| スクリプト VM 評価 | 1.11× | 1.12× |
| 剛体物理学 | 0.43× (速い!) | 1.30× |
| ゲームシミュレーションティック | 0.60× (速い!) | 1.25× |
| レベルウォーク | 0.87× | 0.91× |
| 幾何平均 (21) | 1.12× | 1.24× |
分析結果
- 全体: 平均して
より遅いですが、剛体物理学やゲームシミュレーションティックなど特定タスクでは大幅に高速です。rustc - ネイティブビルドとの比較:
を指定した場合、物理計算などの恩恵は薄れますが、開発時のイテレーション速度向上は無視できません。target-cpu=native - 遅延の原因: 余分な命令(スタックトラフィック、レジスタコピー、ランタイムオーバーヘッド等)によるものです。
Relax は開発反復のために設計されています。 最終的なリリースビルドには必ず
を使用してください。rustc
アーキテクチャとリポジトリ構成
Relax は単一プロセス内ですべてのパイプラインを所有し、並列にコンパイル可能なレイヤー構成を持っています。上位レイヤーの変更は下位レイヤーの再ビルドを発生させません。
クレートスタック
| クレート | パス | 役割 | rustc 相当物 |
|---|---|---|---|
| | レーザ、トークン化、マクロ展開 | Lexer, proc_macro |
| | ハッシュ、メモリ会計、Cfg、Git | Cargo インフラ |
| | セッション管理、キャッシュキー | 增量キー |
| | 解析、名前解決、マクロ展開 | Parser, Resolver |
| | 型チェック、貸借関係チェック | Type Checker |
| | O1/O3 オプティマイザ、JIT コード生成 | MIR + LLVM Opt |
| | コード出力、C ABI 計画、リンカー代替 | CodeGen, Linker |
| | JIT ランタイム、std、インスペクト、テストランナー | Cargo Driver |
| | ネイティブ API インターフェース(JIT 呼び出し) | (独自実装) |
デザインルール
- 決してステインではない: キャッシュ結果はハッシュでキー付けされ、破棄されることはありません。
- コードのみが成長: マシンコードは解放・書き換えせず、安全なスワップを行います。
- デフォルトでの遅延: 必要になるまでコンパイルしません(オンデマンド)。
- 透明性: 全てのフェーズで動作ログを出力し、ボトルネックを可視化できます。
ライセンス
MIT ライセンスを使用しています。Relax がコンパイルする Rust Standard Library (std) のソースには独自のクレジットとライセンスが付帯します(
を参照)。libs/relax/compiler/std/CREDITS.md