3 ポイント 投稿者 GN⁺ 2025-06-19 | 1件のコメント | WhatsAppで共有
  • 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件のコメント

 
GN⁺ 2025-06-19
Hacker Newsの意見
  • Trifecta Techの実装がLinuxディストリビューションで使われている公式実装を置き換える可能性を考えると、以前Fedoraが既存のAdler zlibからzlib-ngへ切り替えた事例もあり、不可能ではないという見方。要点は元実装と互換性のあるC ABIを提供できるかどうか、という意見
    • もし2019年以降アップストリームのリリースがない状況なら、この実装はもう完成しているのではないかという疑問。これ以上修正すべきバグや追加すべき機能がないなら、それ自体で十分だという考え
    • UbuntuがRustで書かれたsudoを使っているため、このような置き換えは十分あり得るという考え
    • Trifecta TechはC ABI互換性をうまく提供しているが、結局は誰かが実際にこの作業をやらなければ変化は起きない、という意見
    • uutilsの目標もこのような公式置き換えにあると言及し、uutils公式サイトへのリンクを共有
    • 軽く見たところ、すでにcargo-c設定が存在していて前向きに見えるが、名前空間が異なるためCプログラムで既存のlibbz2として自動検出はされない状況。bzip2のシンボルに詳しくないので正確なABI互換性は分からないとも言及。GNUオペレーティングシステム向け実装を自分で管理するのは時間がかかって難しく、時間のあるときに実験的プロジェクトのplatyposでPR歓迎という立場
  • 自分はこのcrateを使って数百TBのCommon Crawlデータを処理中。速度が上がって非常に満足しているとのこと
    • ここでbz2を使う理由は何か、という質問。大規模変換を一度だけ行うならzstdへ切り替える利点が大きいと聞いており、圧縮率が高いほどあらゆる面でbzip2より優れているという根拠を提示
    • Common Crawlデータはtorrent形式でも公開されているのか、という質問
    • 圧縮速度14%改善はかなり立派だという感想
  • この実装が、基本的に残っている11件のCVEを解決するのか気になるという声。皮肉にもbzip2 crateにもCVE報告があったとして関連リンクを共有
    • このcrateで報告された「大きなファイルでのランタイム失敗」系の脆弱性と、Cで書かれた場合の「bounds miss」問題との対比が興味深いという意見。こうしたbound miss脆弱性が実際にコード実行までつながるのか気になるという声
    • 「bzip2 crateは0.4.4より前のバージョンに脆弱性がある」という案内を引用。今日0.6.0がリリースされたという補足情報
  • 「90年代のアルゴリズムをなぜわざわざ改良するのか」という問いに対し、最近はどんなアルゴリズムが使われているのか気になるという意見。zstdに言及し、圧縮アルゴリズム比較ベンチマークのリンクを共有
  • CとRustでそれぞれコンパイラのコード生成バックエンドが同じなら、どうして速度向上が起きるのか不思議だという声。Rustのauto-simdや手動最適化、新しい最適化ライブラリの活用など、さまざまな要因の可能性を指摘
    • 推測だが、Rustはコード生成器により多くのヒントを与えられると考えている。例として、Cのポインタと違ってエイリアシングの問題をあまり心配しなくてよい点を挙げ、Aliasingの説明リンクを提示
    • C言語は現代的な高性能コードを書くうえで本当に向いていないという意見。C99〜C21まで約20年のあいだ、言語自体に新しい命令(clz, popcnt, clmul, pdep など)をクリーンな形で活用する機能が不足していたと指摘。こうした抽象化された命令サポートだけでも、この種のコード最適化には大きく役立つと評価
    • どんな言語であれ書き直せば速度改善の機会はあり、Rust固有の速度保証ではないという意見
  • NANAやProssimoに、主要なインターネットプロトコル(BGP、OSPF、RIPなど)やルーティング実装、DNSサーバーなども同じように書き直してほしいという希望
    • ここ数年、Rustなどの安全な言語でインターネットやOSの中核ツールを書き直すことを支援する基金として、NLnetプロジェクトSovereign Tech Fundを紹介。例としてBGP in Rustプロジェクトにも言及
    • Memory Safety Initiativeでは、TLSやDNSなど中核サービスの安全なリライトの取り組みを紹介しており、自分の提案と一部文脈が一致しているとのこと
    • ある開発者がSPARK AdaでIronsides DNSを作ったが、この言語はより強力な形式的証明を支援する
  • macOSではperfプロファイラがなくても、dtraceで十分に性能分析できるという考え。Perlで書かれた元祖flame graphスクリプトもdtraceを使っていたし、Rustで再実装されたflame graphも同じ方式を使う。cache missやmicro instruction retiredのような一部メトリクスは不足するが、それでも非常に有用
  • RustをJavascriptに書き直す必要がある、という冗談めいた意見
  • lbzip2のように並列デコンプレッション(伸長)をサポートしているのか気になるという質問。あるいはblock magicの事前スキャンなどで並列処理が可能なのか、という問い。追記として「たぶんサポートしていないようだ」という結論
  • Lbzip2は全CPUコアを使って非常に高速なデコンプレッション速度を見せてくれた、という体験談。2025年になってもPythonのような多くの主要プログラムが依然として1コアしか使わない状況を惜しむ声
    • Pythonの事情をよく理解していないのでは、という指摘