パフォーマンス
⚠️ 進行中の作業:Vize は積極的に開発中であり、まだ運用環境で使用する準備ができていません。ベンチマークの数値は開発ビルドによるものであり、変更される可能性があります。
Vize は、Rust のゼロコスト抽象化とネイティブ マルチスレッドを活用することで、標準の JavaScript ベースの Vue コンパイラと比較して大幅なパフォーマンスの向上を実現します。スピードはあればいいものではなく、開発者のエクスペリエンスの前提条件です。
ベンチマーク環境
以下の過去の数値は、ローカルのワークステーションで取得されたものです。再現可能な CI ホスト型の場合 リリース ノートやドキュメントの更新に適した番号を使用するには、 Blacksmith ベンチマーク スナップショット ツール ベンチマーク ワークフローによって生成されました。
| 機械 | MacBook Pro (M2 Max、12 コア、96 GB RAM) |
| OS | macOS 15.3.2 (ダーウィン 24.3.0) |
| Node.js | v24.14.0 |
| ヴィート | v8.0.0 (ロールダウン) |
| ビュー | v3.6.0-ベータ.10 |
ベンチマーク: 15,000 SFC ファイル
*15,000 個の Vue SFC ファイル**のコンパイル (合計 36.9 MB):
| @vue/コンパイラ-sfc | ヴィゼ | スピードアップ | |
|---|---|---|---|
| シングルスレッド | 9.35秒 | 3.47秒 | 2.7x |
| マルチスレッド | 4.08秒 | 353ミリ秒 | 11.6x |
| コンパイラー sfc ST と Vize MT | 9.35秒 | 353ミリ秒 | 26.0x |
シングルスレッドの改善は、Rust のゼロコスト抽象化 (GC なし、JIT ウォームアップなし、キャッシュに優しいメモリ レイアウト) から来ています。マルチスレッドの改善は、CPU コア数にほぼ直線的にスケールする Rayon のワークスチール スレッド プールによるものです。
ネイティブのバッチ スケーリング動作
| ファイル | Vize バッチ (1 スレッド) | Vize バッチ (12 スレッド) | 並列高速化 |
|---|---|---|---|
| 100 | 25ミリ秒 | 3ミリ秒 | 8.5倍 |
| 1,000 | 243ミリ秒 | 26ミリ秒 | 9.4倍 |
| 5,000 | 1.25秒 | 128ミリ秒 | 9.7倍 |
| 15,000 | 3.75秒 | 373ミリ秒 | 10.1倍 |
これらのネイティブ バッチ番号には、ファイルの読み取りが含まれます。小さなバッチでは固定オーバーヘッドが大半を占めます。この 12 コア マシンでは、より大きなバッチの並列速度が約 10 倍に落ち着きます。
なぜ錆びるのか?
ゼロコストの抽象化
Rust の所有権モデルにより、ガベージ コレクションの一時停止が不要になります。コンパイラーは、アリーナ割り当て (vize_carton) を通じて AST ノードを処理し、ノードごとのヒープ割り当てを回避します。これはつまり:
GC 一時停止なし— V8 ベースのコンパイラでは、ガベージ コレクションにより、予測できない遅延のスパイクが発生する可能性があります。 Vize には GC オーバーヘッドがありません。
JIT ウォームアップなし— V8 の JIT コンパイラーはホット パスを最適化するのに時間がかかります。 Vize は最初の命令から全速力で実行されます。
予測可能なパフォーマンス— Rust の事前コンパイルは、V8 の最適化ヒューリスティックに依存せず、実行間でパフォーマンスが一貫していることを意味します。
ネイティブ マルチスレッド
Vize はデータ並列コンパイルに Rayon を使用します。各 SFC ファイルは個別にコンパイルされるため、ワークロードは恥ずかしいほど並列になります。 Rayon のワークスチール スケジューラは、最適なコア使用率を保証します。
// Simplified: parallel compilation of all .vue files
files.par_iter().map(|file| {
let arena = Bump::new();
let ast = parse(file, &arena);
let analyzed = analyze(ast, &arena);
compile(analyzed, &arena)
}).collect()
ワークスチールアプローチとは、あるファイルが他のファイルよりも大幅に大きい場合、アイドル状態のスレッドがビジースレッドのキューから作業を奪い、ほぼ完璧な負荷分散を維持することを意味します。
効率的なメモリレイアウト
Rust の構造体レイアウトと列挙型判別式はコンパクトです。 vize_relief の AST 表現はキャッシュに適しており、メモリ帯域幅のボトルネックを軽減します。
列挙型の判別式— Rust の列挙型は、判別式に適合する最小の型にサイズ設定されます。 20 個のバリアントを持つ
NodeKindは、ヒープに割り当てられた文字列ではなく、単一バイトを使用します。構造体のパッキング— Rust は、最適な位置合わせのために構造体フィールドの順序を自動的に変更し、パディングバイトを最小限に抑えます。
オブジェクト ヘッダーなし— JavaScript オブジェクト (プロトタイプ チェーン、プロパティ マップ、および隠しクラス ポインターを運ぶ) とは異なり、Rust 構造体はオーバーヘッドのない純粋なデータです。
実行時のオーバーヘッドなし
V8 で実行される JavaScript ベースのコンパイラーとは異なり、Vize はネイティブ コードに直接コンパイルします。 JIT ウォームアップ、ガベージ コレクター、イベント ループ競合はありません。コンパイラ バイナリは、静的にリンクされた単一の実行可能ファイルであり、フルスピードで起動および実行されます。
パフォーマンスのためのアーキテクチャの選択
アリーナの割り当て
vize_carton は、bumpalo を使用して AST ノードのバンプ アロケーターを提供します。これはつまり:
割り当ては O(1)— ポインタを前方に移動するだけです。フリーリストのトラバーサルや断片化の管理はありません。
割り当て解除は O(1)— コンパイルが完了したら、アリーナ全体を一度に削除します。ノードごとの割り当て解除のオーバーヘッドはありません。
メモリの局所性が優れています— ノードがメモリ内に連続してパックされ、ツリー トラバーサル中の L1/L2 キャッシュ ヒットが最大化されます。
これは、到達可能なオブジェクトを追跡し、メモリを定期的に圧縮する必要がある V8 の世代別ガベージ コレクターに比べて、基本的な利点です。
ストリーミングトークナイザー
vize_armature のトークナイザーは入力をバイト ストリームとして処理するため、中間トークン配列を構築する必要がありません。パーサーはトークンを遅延的に消費します。各トークンはオンデマンドで生成され、すぐに消費されます。これにより、ピーク時のメモリ使用量が削減され、キャッシュの動作が改善されます。
ストリングインターン
共通文字列 (ディレクティブ名、属性名、HTML タグ名) は、compact_str および完全ハッシュ テーブル (phf) を介してインターンされます。これはつまり:
文字列比較は、文字ごとの比較 (O(n)) ではなく、ポインタ比較 (O(1)) です。
重複する文字列は単一の割り当てを共有します
既知の文字列のハッシュ ルックアップはコンパイル時に計算されます
インクリメンタルコンパイル
Vite プラグイン (@vizejs/vite-plugin) はファイルレベルのキャッシュを使用します。開発中には変更されたファイルのみが再コンパイルされ、HMR 遅延が最小限に抑えられます。キャッシュ キーはファイル コンテンツのハッシュであり、変更されていないファイルが再コンパイルされないようにします。
ベンチマーク: Linter — Patina vs eslint-plugin-vue
リンティング15,000 Vue SFC ファイル:
| eslint-プラグイン-vue (ST) | ヴィゼ パティナ (ST) | スピードアップ | eslint-プラグイン-vue (MT) | ヴィゼ パティナ (MT) | スピードアップ | eslint ST 対 Vize MT | |
|---|---|---|---|---|---|---|---|
| 時間 | 45.08秒 | 4.02秒 | 11.2x | 16.38秒 | 784ミリ秒 | 20.9x | 57.5x |
再現するには、vp run --workspace-root bench:lint を実行します。
タイプ認識型 lint プロファイル
タイプ認識リンティングは、コストが集中する傾向があるフェーズ (SFC 解析、 クロッキー分析、仮想 TypeScript 生成、テンプレート クエリ コレクション、および Corsa プローブ。いつ 複数のテンプレートに基づく型認識ルールが有効になっており、Patina はテンプレート式を収集し、 テンプレート Corsa プローブ フェーズの前の 1 つの AST ウォークでの Promise クエリ。クエリコレクションも共有 OXC 式は安全でないテンプレートとフローティング Promise チェックを解析するため、1 つのテンプレート式 両方のルールが有効な場合、重複した解析コストは発生しません。
vize lint --profile --preset opinionated src を実行して、ローカル プロジェクト内のこれらの行を表示します。の
プロファイル レポートには、経過時間カバレッジ、累積的なデータをチェックする厳密な監査セクションも含まれています。
ホットファイルと内部をリストする前に、ワーカー時間、低速しきい値ヒット、キャプチャされた内部スパンを確認します。
操作。ホットファイル行はステージごとのシェアとスループットを示し、操作行は支配的なフラグを示します
スパンまたは最大/平均スパイク。
ベンチマーク: フォーマッタ — グリフと Prettier
*15,000 個の Vue SFC ファイル**のフォーマット:
| プリティア (CLI) | ヴィゼグリフ(ST) | スピードアップ | ヴィゼグリフ(MT) | Prettier CLI と Vize MT | |
|---|---|---|---|---|---|
| 時間 | 101.20秒 | 2.97秒 | 34.1x | 835ミリ秒 | 121.2x |
再現するには、vp run --workspace-root bench:fmt を実行します。
ベンチマーク: 型チェッカー — canon 対 vue-tsc
現在の Corsa-backed 診断パスを使用して500 個の生成された Vue SFC ファイルをタイプ チェックします。
| vue-tsc (ST) | ヴィゼカノン (ST) | スピードアップ | vue-tsc (MT) | ヴィゼカノン (MT) | スピードアップ | vue-tsc ST と Vize MT | |
|---|---|---|---|---|---|---|---|
| 時間 | 4.38秒 | 511ミリ秒 | 8.6x | 4.41秒 | 493ミリ秒 | 8.9x | 8.9x |
| 料金 | 114 ファイル/秒 | 979 ファイル/秒 | 113 ファイル/秒 | 1.0k ファイル/秒 |
注意:Vize canon はまだ開発初期段階にあり、Corsa を利用した診断パスは vue-tsc の忠実度にまだ追いついていません。これらの測定値は、プロジェクト セッション フォールバックを備えた現在の CLI ファースト ネイティブ実装を反映しており、診断カバレッジとパリティが向上するにつれて変化します。
この簡単なベンチマークを再現するには、cargo build --release -p vize の後に node bench/check.ts 500 を実行します。
タイプチェッカープロファイル
500-SFC プロファイル フィクスチャは、Corsa CLI コマンド内でのほとんどの所要時間を維持しますが、インポート リライト高速パスにより、Vue 指定子のないファイルに対する以前の OXC 解析コストが削除されます。
| メトリック | 前 | 現在 |
|---|---|---|
canon.import.rewrite.vue |
26.77ミリ秒 | 2.45ミリ秒 |
| 生成された最大の仮想 TS | 15,401B | 14,414B |
| プロファイルの合計経過時間 | 1.88秒 | 668ミリ秒 |
| Corsa 診断フェーズ | 1.67秒 | 482ミリ秒 |
| Corsa CLI 解析 | 該当なし | 10.41ミリ秒 |
Rust 側の virtual project フェーズ — ファイルごとの SFC 解析、クロッキー解析、
仮想 TS の生成とインポートの書き換え — rayon のスレッド全体で扇動されます
VirtualProject::register_paths内のプール。各 .vue ファイルは独立しています
ワークスペース オプションが解決されると、単一のバッチが並列化されます。
きれいに。 1,000-SFC フィクスチャでは、位相が約 71 ms から約 25 ms に低下します。
コルサも発動する。
診断を多用する e2e フィクスチャ
bench/check.ts は、フィクスチャが存在する場合、tests/_fixtures/_git/npmx.dev アプリも測定します。これにより、実際のアプリケーション フィクスチャ上の診断マッピング パスが取得されます。
| 治具 | ソース SFC ファイル | 仮想ファイル | 診断 | ヴィゼカノン |
|---|---|---|---|---|
| npmx.dev アプリ | 134 | 226 | 1,053 | 1.94秒 |
このフィクスチャの現在のプロファイルでは、CLI 診断解析が約 7 ミリ秒に維持されます。現在、ほとんどの時間は Corsa CLI コマンド自体に費やされています。フレームワークの自動インポート スタブを 1 つのアンビエント ファイルにホイストすると、生成される最大の仮想 TS ファイルも約 275 KB から 144 KB に削減されました。
ベンチマーク: Vite プラグイン — @vizejs/vite-plugin 対 @vitejs/plugin-vue
*1,000 個の Vue SFC インポート**を含む Vite ビルド (すべて 1 つのエントリでインポート):
| @vitejs/plugin-vue | @vizejs/vite-plugin | スピードアップ | |
|---|---|---|---|
| ビルド時間 | 957ミリ秒 | 479ミリ秒 | 2.0x |
注:
@vizejs/vite-pluginは Vue SFC コンパイル手順のみを置き換えます。パフォーマンスの違いは完全にその部分から生じます。依存関係の解決、モジュール グラフの構築、バンドル (ロールダウン)、およびその他すべての Vite 内部は@vitejs/plugin-vueと同一です。純粋なコンパイルのパフォーマンスについては、上記の コンパイラ ベンチマーク を参照してください。@vizejs/vite-pluginは、ネイティブ マルチスレッド コンパイルを使用して.vueファイルを積極的にプリコンパイルします。これにより、より高速な HMR も可能になります。
再現するには、vp run --workspace-root bench:vite を実行します。