RustとC++のコンパイル時間を比較する
(quick-lint-js.com)別の場所で面白い記事を読んだので紹介します。
RustとC++はさまざまな面で比較対象になることがあります。しかし、コンパイル時間を直接比較するには、同じプロジェクトが両方の言語で書かれているケースがまれなため難しい状況でした。quick-lint-jsは、C++で書かれたプロジェクトの一部をRustで書き直し、コンパイル時間を比較したそうです。ただし、コンパイル環境からはWindowsが除外されています。
移植の基準
- サードパーティーライブラリを除外
- LinuxおよびmacOSで作業
- 広範なテストスイート
- FFI、ポインタ、標準および自作のコンテナ、ユーティリティクラスと関数、I/O、並行性、ジェネリクス、マクロ、SIMD、継承、...
結論
- Rustのコンパイル時間はC++と同程度か、より遅い(少なくともこのプロジェクトでは)
- RustはC++よりも多くのコードを書く必要がある
- 全体(Full)ビルドではC++が同程度かより速い
- 増分(Incremental)ビルドでは短いこともあれば長いこともある(非常に長い場合もある)
- quick-lint-jsの残りはRustへ移植しないことを決定(ビルド時間の改善があれば行うかも?)
4件のコメント
国内でもRustを使っている方が多いですね。皆さんがどんな業界で働いているのか気になります。
1回目のコンパイル後、C++は依存関係の多いヘッダではなく単一のcppファイルを修正すればすぐにコンパイルできますが、Rustはどうなのか気になりますね。
RustとC++のコンパイル時間を比較してみる
RustのドキュメントのFAQ欄に関連内容が詳しく説明されていたので、共有します。
====================================
Rustのコンパイルは遅いように思えます。なぜですか?
コードを機械語に変換し、最適化を行うためです。Rustは効率的な機械語にコンパイルされる高水準の抽象化を提供しており、この変換プロセスには、特に最適化を行う場合、時間がかかるものです。
しかし、Rustのコンパイル時間は思われているほど悪くはなく、今後さらに改善されると考えられる理由もあります。C++とRustで同程度の規模のプロジェクトを比較すると、プロジェクト全体をコンパイルする時間は一般的に似通っていると見られます。Rustのコンパイルが遅いと感じる主な原因は、C++とRustでコンパイルモデルが異なること、つまりC++のコンパイル単位は1ファイルであるのに対し、Rustは複数のファイルから成るcrateであることにあります。そのため、開発中にC++のファイルを1つ修正した場合、Rustに比べてコンパイル時間が大幅に短くなることがあります。現在、Rustコンパイラをリファクタリングしてインクリメンタルコンパイルを可能にしようとする大規模な作業が進行中であり、完了すればRustでもC++のモデルのようにコンパイル時間が改善されるでしょう。
コンパイルモデルとは別に、Rustの言語設計にはコンパイル時間に影響する要素がいくつかあります。
まず、Rustは比較的複雑な型システムを持っており、実行時にRustを安全にするための制約を強制するために、無視できないコンパイル時間を費やす必要があります。
次に、Rustコンパイラには古い技術的負債があり、とりわけ生成されるLLVM IRの品質が高くないため、LLVMが時間をかけてそれを「修正」しなければなりません。将来的には、MIRベースの最適化および変換段階によって、RustコンパイラがLLVMにかける負荷が軽減されるかもしれません。
3つ目に、Rustがコード生成にLLVMを使っていることは諸刃の剣だという点です。LLVMのおかげでRustは世界トップクラスのランタイム性能を発揮しますが、LLVMはコンパイル時間に焦点を当てていない巨大なフレームワークであり、とりわけ品質の低い入力に弱いという面があります。
最後に、Rustがジェネリック型をC++と似た形で単相化(monomorphise)する戦略は高速なコードを生成しますが、他の変換戦略に比べてかなり多くのコードを生成しなければならないという問題があります。このコード膨張については、trait objectを使うことで動的ディスパッチと長短所を交換できます。
確かなのは、Rust のプロジェクトはビルド中にディスクをものすごく食うことですね。ライブラリを100個あまり取り込んで使ったプロジェクトが、いつの間にか 2GB ほど使っているのを見て驚いた記憶があります……