1742163938
2025-03-16 19:35:00
バージョンをリリースしました 0.4.2 の Zlib-rs、多くの大幅なパフォーマンスの改善を特徴としています。私たちは今(私たちの知る限り)減圧のための最速のAPI互換ZLIB実装であり、最も重要な圧縮ケースの競争にも勝ちました。
私たちはaを構築しました ダッシュボード これは、他の実装と比較して現在のメインブランチのパフォーマンスを示し、時間の経過とともにパフォーマンスを追跡して、回帰をキャッチし、進捗状況を視覚化します。
この投稿では、ZLIB-RSを最新のものと比較しています zlib-nng そして、減圧のために、 Zlib-Chromium。これらは、パフォーマンスに焦点を当てた主要なC ZLIB実装です。すぐに、より技術的な詳細が記載されたブログ投稿を作成し、最も影響力のある変更を簡単にカバーします。
減圧
前回、を使用してベンチマークしました target-cpu=native フラグ。それは私たちの実装に最良の結果をもたらしましたが、私たちの錆の実装は特定のSIMD機能が利用可能になると仮定することができるため、完全に公平ではありませんでしたが、Zlib-ngは実行時にそれらを確認する必要がありました。
現在、いくつかの変更を加えて、実行時に最も最適な実装を効率的に選択できるようにしました。
多額
関数の最高のバージョンを選択することは、マルチソリオンと呼ばれます。すべてのCPUで動作するベースラインの実装があり、その後、特定のCPUで利用可能な場合と使用できない場合があるSIMD命令またはその他の機能を使用するいくつかの専門的なバージョンがあります。課題は、常に最適な実装を選択することですが、ランタイムコストは最小限です。つまり、ランタイムチェックをできるだけ少なくして、大量の作業を実行したいと考えています。
今日、マルチソリオンは錆でネイティブにサポートされていません。がある それを追加するための提案 (これは非常に興奮しています!)、今のところ、残念ながら安全でないコードが含まれる手動で実装する必要があります。これについてはすぐに書きます(焦りますが、関連するコードは ここ)。
DFAの最適化
Cコードは使用できます switch 非常に効率的なコードを生成するための暗黙のフォールスルー。 Rustはこのメカニズムに相当するものではなく、これにより、データが小さなチャンクに入ると、本当に遅くなりました。
ニキータ・ポポフは私たちが試してみることを提案しました -Cllvm-args=-enable-dfa-jump-thread ここでパフォーマンスのほとんどを回復するオプション。決定論的な有限オートマトンのために一種のジャンプスレッドを実行し、減圧ロジックがこのパターンと一致します。
LLVMは現在、このフラグをデフォルトで有効にしていませんが、最終的には計画です。また、RUSTC自体でのこの最適化のサポートを検討し、プロジェクト全体に盲目的に適用し、最高のものを期待するよりも細かく粒度を高めています。
これらの努力はの一部です 提案されたプロジェクト目標 そして Trifecta Tech Foundationのコード生成イニシアチブ。
ベンチマーク
私たちが知る限り、私たちは減圧のための今日の最速のAPI互換ZLIB実装です。 Zlib-NGを公正なマージンで倒すだけでなく、Chromiumで使用される実装よりも速くなります。
以前と同じように、私たちのベンチマークは、Silesia-Small.tarの圧縮バージョンを減圧し、状態マシンにPower-of-2サイズのチャンクの入力に供給しています。小さなチャンクサイズは、ストリーミングユースケースをシミュレートし、より大きなチャンクサイズモデルケースが完全な入力が利用可能であるケースをシミュレートします。
対zlib-nng
現在、最小のチャンクサイズを除くすべての場合、Zlib-ngよりも大幅に高速です。のチャンクサイズ 2^4 = 16 入力をバッファリングし、より大きなチャンクで減圧することができるため、バイトは実際のパフォーマンスに関連する可能性は非常に低いです。
ただし、より関連性の高いチャンクサイズでは、Zlib-Ngよりも大幅に高速です。1KBの入力では10%をはるかに超え、65kbの入力で6%を超えています。
| チャンクサイズ | zlib-nng | Zlib-rs | d |
|---|---|---|---|
| 4 | 255.77M ± 179.04K |
259.40M ± 492.87K |
💩 +1.40% |
| 5 | 203.64M ± 305.47K |
190.91M ± 343.64K |
🚀 -6.67% |
| 6 | 164.30M ± 131.44K |
148.51M ± 193.07K |
🚀 -10.63% |
| 7 | 142.62M ± 156.88K |
126.24M ± 113.62K |
🚀 -12.98% |
| 8 | 131.87M ± 210.99K |
116.36M ± 116.36K |
🚀 -13.33% |
| 9 | 126.19M ± 227.14K |
111.99M ± 100.79K |
🚀 -12.68% |
| 10 | 125.58M ± 150.70K |
111.18M ± 111.18K |
🚀 -12.95% |
| 11 | 123.94M ± 136.34K |
112.16M ± 201.89K |
🚀 -10.50% |
| 12 | 121.81M ± 109.63K |
111.82M ± 89.45K |
🚀 -8.94% |
| 13 | 114.27M ± 114.27K |
106.27M ± 138.15K |
🚀 -7.53% |
| 14 | 102.34M ± 133.04K |
95.13M ± 95.13K |
🚀 -7.57% |
| 15 | 94.35M ± 132.09K |
87.72M ± 96.49K |
🚀 -7.56% |
| 16 | 90.40M ± 108.48K |
84.53M ± 84.53K |
🚀 -6.94% |
対クロム
減圧のために、Chromiumプロジェクトで使用されるZLIB実装(見つかりました ここ、それを介して使用します の修正バージョン libz-sys)Zlib-ngよりも速いことがよくあります。ただし、最も関連性の高いチャンクサイズのこのベンチマークでも打ち負かしました。

興味深いことに、Zlib-Chromiumは塊のサイズが小さい場合にほぼ速くなりますが、より大きなチャンクサイズのパフォーマンスはZlib-Ngにかなり匹敵します。
| チャンクサイズ | Zlib-Chromium | Zlib-rs | d |
|---|---|---|---|
| 4 | 227.39M ± 363.82K |
259.40M ± 492.87K |
💩 +12.34% |
| 5 | 181.29M ± 471.36K |
190.91M ± 343.64K |
💩 +5.04% |
| 6 | 146.09M ± 160.70K |
148.51M ± 193.07K |
💩 +1.63% |
| 7 | 126.91M ± 164.98K |
126.24M ± 113.62K |
🚀 -0.53% |
| 8 | 118.13M ± 94.51K |
116.36M ± 116.36K |
🚀 -1.53% |
| 9 | 114.83M ± 91.86K |
111.99M ± 100.79K |
🚀 -2.53% |
| 10 | 113.20M ± 90.56K |
111.18M ± 111.18K |
🚀 -1.82% |
| 11 | 114.20M ± 102.78K |
112.16M ± 201.89K |
🚀 -1.81% |
| 12 | 114.55M ± 103.10K |
111.82M ± 89.45K |
🚀 -2.44% |
| 13 | 108.87M ± 87.09K |
106.27M ± 138.15K |
🚀 -2.44% |
| 14 | 99.55M ± 129.41K |
95.13M ± 95.13K |
🚀 -4.64% |
| 15 | 92.35M ± 157.00K |
87.72M ± 96.49K |
🚀 -5.28% |
| 16 | 90.01M ± 180.02K |
84.53M ± 84.53K |
🚀 -6.48% |
圧縮
私たちもコンプレッションに欠けていました(叫び声を上げています ブライアンペイン、この分野で多数のPRを寄付しましたが、より多くの複雑な結果が見られます。

X86_64 Linuxでは、最も重要な圧縮レベルのいくつか、デフォルトレベルで6%、「最高の圧縮」レベル9で10%以上で高速になります。
| 圧縮レベル | の | Rs | d |
|---|---|---|---|
| 0 | 15.07M ± 272.75K |
14.83M ± 260.97K |
🚀 -1.63% |
| 1 | 250.09M ± 300.11K |
258.71M ± 388.06K |
💩 +3.33% |
| 2 | 436.59M ± 698.54K |
465.33M ± 418.80K |
💩 +6.18% |
| 3 | 523.10M ± 156.93K |
542.28M ± 325.37K |
💩 +3.54% |
| 4 | 623.40M ± 436.38K |
648.43M ± 324.22K |
💩 +3.86% |
| 5 | 773.30M ± 463.98K |
711.81M ± 427.09K |
🚀 -8.64% |
| 6 | 939.52M ± 469.76K |
884.79M ± 442.39K |
🚀 -6.19% |
| 7 | 1.23G ± 1.48M |
1.24G ± 617.75K |
💩 +0.38% |
| 8 | 1.59G ± 159.22K |
1.60G ± 1.92M |
💩 +0.48% |
| 9 | 1.94G ± 970.95K |
1.71G ± 512.66K |
🚀 -13.64% |
ほとんどのユーザーにとって、減圧が最も関連性の高い操作であり、圧縮であっても、ストックZLIBよりもはるかに高速です。それにもかかわらず、私たちは引き続き圧縮性能を向上させようとします。
結論
ZLIB-RSは、Cプロジェクトでも、錆プロジェクトでも錆びたクレートとして使用できます。さびプロジェクトには、を使用することをお勧めします 1.1.0 のリリース flate2 のクレート zlib-rs 機能フラグ。 Cプロジェクトで使用するために、ZLIB-RSはCダイナミックライブラリとして構築できます(参照 説明書)そして、今日Zlibを使用しているプロジェクトで使用されています。
私たちの実装はほとんど行われており、明らかに非常にうまく機能します。しかし、私たちはいくつか欠けています あまり一般的ではないAPI関数 すべての場合に完全なドロップイン交換になるGZIPファイルに関連しています。
作業を完了し、パフォーマンスを改善し、たとえばパッケージングを改善するために、95.000ユーロの金額の資金を求めています。を参照してください 職場 詳細については。
お願いします お問い合わせ ZLIB-RSの財政的にサポートすることに興味がある場合。
#ZLIBRSはcよりも高速です