bzip2クレートがCから100% Rustへ移行
(trifectatech.org)- bzip2クレートが Cコードへの依存を100% Rust 実装に置き換えた
- 性能 が従来より全体的に向上し、クロスコンパイルも容易になった
- Rust実装は C版 と比べてデータの圧縮・展開速度の両方が改善されている
- シンボル衝突 問題のようなライブラリ依存関係の課題が大幅に減少した
- セキュリティ監査を経て 重要なロジックバグ を修正し、安定性が検証された
bzip2クレート 0.6.0 リリースとRustベースへの移行
- 本日、bzip2 バージョン 0.6.0 が公開された
- これからはデフォルトで、自前で開発した Rust ベースの bzip2 アルゴリズム実装 libbz2-rs-sys を使用する
- この移行により、bzip2クレートはより高速になり、クロスコンパイルも容易になった
- libbz2-rs-sysクレートは C 動的ライブラリとしてもビルド可能。これにより C プロジェクトでも性能向上の恩恵を受けられる
なぜこの移行が行われたのか?
- bzip2 アルゴリズムは90年代に作られ、現在では広く使われているわけではないが、複数のプロトコルやライブラリで今なお 仕様準拠 のために必要とされている
- 多くのプロジェクトは直接ではなくても、依存関係ツリーのどこか深い場所で bzip2 に依存している
- これまで zlib-rs で蓄積した経験をもとに、今回 bzip2 実装をモダナイズした
- libbz2-rs-sys の実装詳細は以前のブログ記事で扱っている。ここでは今回の移行による 利点 を見ていく
向上した性能
- Rust 実装は全体的に C版 より高い性能を示している
- 一部の状況では同等の性能だが、遅くなるケースはない
- 圧縮性能: bzip2 には level オプションがあるが、性能への影響はわずか
- テスト結果では、代表的なサンプルファイルで Rust 版が 10% 以上高速化した
圧縮:
| ファイル | C(実行サイクル) | Rust(実行サイクル) | 相対変化 |
|---|---|---|---|
| sample3.ref (level 1) | 38.51M | 33.53M | -14.87% |
| silesia-small.tar (level 1) | 3.43G | 3.00G | -14.30% |
| silesia-small.tar (level 9) | 3.47G | 3.17G | -9.66% |
展開でもすべてのケースで性能向上が見られた:
| ファイル | C(実行サイクル) | Rust(実行サイクル) | 相対変化 |
|---|---|---|---|
| sample3.bz2 | 2.53M | 2.42M | -4.48% |
| sample1.bz2 | 9.63M | 8.86M | -8.63% |
| sample2.bz2 | 20.47M | 19.02M | -7.67% |
| dancing-color.ps.bz2 | 87.46M | 83.16M | -5.17% |
| re2-exhaustive.txt.bz2 | 1.89G | 1.76G | -7.65% |
| zip64support.tar.bz2 | 2.32G | 2.11G | -10.00% |
ただし、macOS 環境では圧縮・展開の数値に変動が出ることがある。性能測定ツールの制約により分析は難しかった
クロスコンパイル対応
- C 依存のある Rust プロジェクトのクロスコンパイルは、通常は cc クレートのおかげでうまく動作するが、失敗した場合のデバッグは非常に難しい
- システムライブラリのリンク過程で予期しない問題が起こりやすく、WebAssembly ビルドを含む一部環境では実質的な障害要因となる
- Rust 実装へ移行したことで、C 関連の問題は 完全になくなった
- これにより、Windows、Android、WebAssembly などでも特記事項なくクロスコンパイルが可能になった
- これはユーザー体験だけでなく、保守性の観点からも大きな利点だ
デフォルトでシンボル(export)衝突なし
- C 依存では Rust の extern ブロック外でシンボルを export する必要があるため、他の依存関係が同じシンボルを export すると衝突が発生する
- libbz2-rs-sys は デフォルトでシンボルを export しないよう設計 されている
- そのため、他の外部ライブラリとシンボル衝突が起きることはない。必要であれば feature flag で export を有効化することもできる
MIRIベースのテスト実行
- Rust で bzip2 を高性能に実装するには unsafe コード の利用が避けられず、C インターフェースの再現にも多くの unsafe コードが必要になる
- 幸い、このコードは MIRI 環境で実行・テストできる
- さらに、bzip2 を利用する上位レベルのライブラリやアプリケーションでも、今後は MIRI テストが可能になる
結論
bzip2クレートはより高速になった。もはや意識する必要がないほど自然に、より良い体験を提供する
1件のコメント
Hacker Newsの意見