LabHub

ブログ

圧縮アルゴリズム Deep Dive — LZ77, Huffman, Arithmetic, ANS, Zstandard, Brotli 完全理解 (2025)

한국어English日本語

TL;DR


1. 圧縮の基本

1.1 なぜ圧縮するのか

2025 年、データは爆発的に増えており圧縮の重要性はむしろ増している。CPU は余っているが I/O とネットワークがボトルネック。

1.2 Lossless と Lossy

Lossless (本稿):

Lossy:

1.3 Shannon の限界

情報理論 (Claude Shannon, 1948) によれば、任意のデータに圧縮の 理論的下限 が存在する。エントロピー:

H(X)=ipilog2piH(X) = -\sum_i p_i \log_2 p_i

p_i は記号 i の確率。単位は bit/symbol。

英文のエントロピーは約 1.5 bit/char。8-bit ASCII で保存されたテキストは理論上 5 倍以上圧縮 可能。現実の圧縮器は限界に近づくが到達はできない。

1.4 2 段戦略

現代の可逆圧縮器はほぼ 2 段 を組み合わせる:

  1. Dictionary / LZ: "ABCDEF...ABCDEF" のような反復を back-reference で置換。構造的冗長性 を除去。
  2. Entropy coding: 残ったバイトの 統計的偏り を活用。頻出文字に短符号、稀文字に長符号。

2 段は独立に発展しており、どの LZ とどの Entropy を組み合わせるかで異なる compressor になる。


2. LZ77 — すべての起源

2.1 アイデア

Lempel と Ziv の 1977 年論文。「反復されたシーケンスを以前の位置参照で置換する」。

入力: ABABABAB

A          -> "A" (literal)
B          -> "B" (literal)
AB         -> "位置 -2 から 2 バイトコピー"
AB         -> "位置 -2 から 2 バイトコピー"

出力:

(0, 0, A)
(0, 0, B)
(2, 2, _)
(2, 2, _)

各トークン (offset, length, next_char)

2.2 Sliding Window

実装では 直近 N バイトの窓 だけを検索する。

[search buffer (N bytes)] [lookahead buffer (M bytes)] [未処理データ]

各ステップ: lookahead の先頭が search buffer のどこに現れたか探す -> 最長 match を選ぶ -> (offset, length, next_char) 出力 -> length + 1 だけ進める。

2.3 LZSS (1982)

LZ77 の改良: match が短すぎると back-reference の方が損。LZSS は flag bit でリテラルか参照かを区別し、3 バイト以上のみ参照にする。ほとんどの modern compressor は LZSS の派生。

2.4 LZ78 と LZW

LZ78: Sliding Window の代わりに 明示的 Dictionary を構築。LZW (Welch, 1984) は派生で GIF、Unix compress、旧 PDF で使われた。現在はほぼ廃れ、LZ77 系が支配。

2.5 Back-reference の効率

1 MB の反復テキスト:

32 倍圧縮。原理は「反復を指す」の一言。

2.6 Hash ベースの Matching

各位置での最長 match 検索がボトルネック。解決策: hash chain。3 バイト prefix にハッシュを計算し、同じハッシュの過去位置を連結リストで繋ぐ。候補を高速に取得。

速度 vs 圧縮率:

これが gzip -1gzip -9 の差。


3. Huffman Coding

3.1 アイデア

David Huffman (1952 年、MIT 院生の課題)。「よく出る記号に短い符号、稀な記号に長い符号」。

頻度例:

a: 40%
b: 20%
c: 15%
d: 15%
e: 10%

固定 3-bit だと 3 bit/symbol。Huffman:

a -> 0     (1 bit)
b -> 10    (2 bits)
c -> 110   (3 bits)
d -> 1110  (4 bits)
e -> 1111  (4 bits)

平均: 0.4x1 + 0.2x2 + 0.15x3 + 0.15x4 + 0.10x4 = 2.25 bit/symbol。25% 削減

3.2 Prefix-free の性質

どの符号も他の符号の接頭辞にならない (例: 0, 10, 110)。区切り子なしで連続デコード可能。

01001101110 -> 0 10 0 110 1110 -> a b a c d

3.3 Huffman Tree

二分木で各記号にパスを割り当て。葉が記号、パスが符号 (左=0、右=1)、頻出記号は 短いパス

3.4 Tree 構築

  1. すべての記号を頻度順の優先キューに投入。
  2. 最小 2 ノードを取り出し、頻度の和を持つ親ノードに統合。
  3. 親をキューに戻す。
  4. 1 つになるまで繰り返し。

O(n log n)。貪欲だが 最適な prefix-free 符号 であることが証明されている。

3.5 Canonical Huffman

同じ頻度でも木の形は複数ある。Canonical form は符号長だけを保存し規則的に割り当てる -> メタデータが小さい。Deflate と現代の圧縮器の大半で採用。

3.6 限界

Huffman の限界:

この限界を Arithmetic codingANS が乗り越える。


4. Arithmetic Coding

4.1 アイデア

「メッセージ全体を 1 つの実数 で表す」。任意分布に対して理論限界に近づける。

4.2 例

アルファベット a (50%), b (25%), c (25%)。"abc" を区間 [0, 1) から符号化。

  1. 'a' 入力: 区間 = [0, 0.5)
  2. 'b' 入力: 区間 = [0.25, 0.375)
  3. 'c' 入力: 区間 = [0.34375, 0.375)

この区間内の 任意の実数 を出力 (例: 0.35、2 進 01011010)。Decoder は同じ確率分布で逆算。

4.3 効率

各記号が正確に -log2(p) bit を占有。Shannon エントロピー限界に接近。Huffman は整数 bit、Arithmetic は実数 bit。

4.4 なぜ限定的か

30 年間、「より良い方法はあるが実用的ではない」という位置づけ。H.264、JPEG 2000 で利用。

4.5 Range Coding

Arithmetic coding の派生。整数演算を使い特許を回避。LZMA (7zip) で使用。


5. ANS — ゲームチェンジャー

5.1 背景

2009 年、ポーランドの数学者 Jarek Duda が新エントロピー符号 ANS (Asymmetric Numeral Systems) を提案。メーリングリストと論文で静かに公開。のちに 「Arithmetic の品質 + Huffman の速度」 と評価され急速に採用。

5.2 アイデア

「1 つの大きな整数」にメッセージ全体を符号化。ただし標準レジスタ演算で。Arithmetic coding のように動くが 浮動小数なし、除算ほぼなし。代わりに Finite State Machine として表現。

5.3 Finite State Entropy (FSE)

ANS の実用派生。Zstd 作者の Yann Collet が実装。

状態機械は 事前計算テーブル -> 実行時は lookup + shift のみ -> 非常に高速。

5.4 tANS と rANS

Zstd の FSE は tANS。Facebook の一部内部ツールは rANS。

5.5 性能

項目HuffmanArithmeticFSE
圧縮率基準-0.5% ~ -3%-0.5% ~ -3%
符号化速度1x0.3-0.5x1.2-2x (より速い!)
復号速度1x0.3-0.5x1.5-2x

「欠点のないアップグレード」。なぜもっと早くなかったのか疑問。

5.6 採用

ANS ベースの compressor:

2015 年以降の新しい圧縮器における 事実上の標準エントロピー符号


6. Deflate — gzip のエンジン

6.1 概要

Phil Katz の 1993 年作。PKZIP で利用、RFC 1951 (1996) として標準化。LZ77 + Huffman。最も広く使われる圧縮フォーマット: gzip, ZIP, PNG, Content-Encoding: gzip。30 年以上の標準。

6.2 構造

圧縮データ = block のシーケンス。各 block:

6.3 LZ77 段

各 match は (length, distance) ペア、リテラルは 0-255 の文字コード。

6.4 Huffman 段

2 本の Huffman tree:

長さと距離は log スケールの bucket にマップ。小さな値は正確に、大きな値は extra bits で表現。

6.5 レベル

gzip -1 ~ gzip -9:

Time/space トレードオフ。比率差 ~20% / 速度差 5-10 倍。

6.6 性能

30 年前のアルゴリズムだが依然有用。とはいえ現代の zstd/brotli がより優秀。


7. LZ4 — 極限の速度

7.1 哲学

Yann Collet の 2011 年作。「圧縮率を犠牲にして速度を極大化」。

7.2 設計

7.3 速度

CPU がディスクやネットワークより速い環境に最適。

7.4 使われる場所

「リアルタイム圧縮が必要だが CPU 予算が限られる」場所。

7.5 LZ4 HC

High Compression 派生。より遅いが比率が良い。それでも zstd より速く圧縮率は低い。

7.6 Snappy

Google の類似圧縮器 (2011)。非常に高速で比率低め、LevelDB、BigTable、HBase で使用。LZ4 の方がやや速くやや圧縮するので大抵 LZ4 が勝つ。


8. Zstandard — 汎用の王

8.1 背景

Facebook の Yann Collet (LZ4 と同じ作者)、2016 年発表。目標「gzip より 3 倍速く、よりよく圧縮」。

8.2 構成

8.3 Dictionary 機能

Killer feature: pre-trained Dictionary。

# 100 個の JSON サンプルから Dictionary を学習
zstd --train samples/*.json -o dict.bin

# Dictionary を用いて圧縮
zstd -D dict.bin input.json -o output.zst

# Dictionary を用いて解凍
zstd -D dict.bin -d output.zst -o input.json

効果: 小さなメッセージ (数百バイト) で 10-100 倍の圧縮率改善。通常の圧縮器は小さな payload に弱いが Zstd + Dictionary で克服。Kafka、小さな HTTP API、チャットに最適。

8.4 Long-range モード

zstd --long: 遠く離れた match まで検索 (GB 単位の window)。バックアップ、ディスクイメージに効果的。

8.5 圧縮レベル

zstd -1 (fast) ~ zstd -22 (max):

8.6 解凍速度

2-3 GB/s (単一コア)。圧縮レベルに無関係、常に高速 — これが最大の強み。

8.7 採用

事実上の新標準

8.8 コード複雑さ

Zstd のソースは ~25,000 行 C、gzip は ~5,000 行。複雑さ vs 性能のトレードオフだが 単一バイナリ、外部依存なし でポート容易。


9. Brotli — Google の選択

9.1 背景

Google の Jyrki Alakuijala 他、2015 年発表。HTTP/2 コンテンツ圧縮用。

特徴:

9.2 圧縮率

Zstd と同程度の比率で やや遅い。HTML/CSS/JS に最適化、Web コンテンツでは内蔵 Dictionary のおかげで Zstd よりやや良い。

9.3 解凍

~400 MB/s。Zstd よりやや遅いが十分。

9.4 使われる場所

主に Web:

汎用システムでは zstd が主。

9.5 Brotli vs Zstd (Web)

10 MB HTML + CSS + JS
gzip (-9):   2.5 MB
brotli (11): 1.8 MB  (gzip より 28% 小)
zstd (19):   1.9 MB

Web では Brotli が静的 Dictionary により僅差で優位。


10. LZMA / 7z

10.1 背景

Igor Pavlov の LZMA (Lempel-Ziv-Markov chain-Algorithm)。7-zip の既定、1998 年から。

10.2 特徴

10.3 性能

10.4 使われる場所

「極限の圧縮率が必要で時間がある」場合。バックアップ、配布ファイル。

10.5 なぜ zstd が置き換えるのか

Zstd: 比率は少し劣るが はるかに高速。Arch の xz -> zstd 移行報告では「インストール時間 50% 短縮、パッケージサイズ 20% 増加」。ユーザー視点でネットポジティブ。


11. 比較表

11.1 圧縮率

テキスト入力 (10 MB Linux kernel source):

アルゴリズムRatioCompressDecompress
LZ4 -12.1x700 MB/s3500 MB/s
LZ4 -9 (HC)2.5x30 MB/s3500 MB/s
Snappy2.0x600 MB/s2500 MB/s
gzip -12.7x200 MB/s400 MB/s
gzip -93.2x20 MB/s400 MB/s
zstd -12.8x500 MB/s2500 MB/s
zstd -33.4x250 MB/s2500 MB/s
zstd -93.6x80 MB/s2500 MB/s
zstd -194.0x10 MB/s2500 MB/s
brotli -114.1x8 MB/s400 MB/s
xz -94.3x3 MB/s70 MB/s

11.2 用途別の推奨


12. SIMD 加速

12.1 機会

圧縮は逐次処理だが多くの部分で SIMD が効く:

  1. Hash 計算: 複数位置を一度に。
  2. Match 検索: 長い byte 比較。
  3. Huffman 復号: 並列 lookup。
  4. Entropy 復号: ANS state 更新。

12.2 現代の実装

12.3 帯域の限界

多くの場合 メモリ帯域 が実質ボトルネック。SIMD で CPU を減らしても L3/DRAM の帯域が飽和。数 GB/s を超えるとハードウェアの限界。

12.4 ハードウェア圧縮

大規模サービス (Facebook, Google) が活用。


13. Dictionary Training

13.1 なぜ必要か

通常の圧縮器は入力内の重複のみを探す。100 バイトの JSON には内部重複がほぼないため圧縮されない。

{"name":"Alice","age":30}

このメッセージはメタデータのオーバーヘッドで むしろ大きくなる こともある。

13.2 Dictionary の役割

似た JSON を数百個見ると 共通パターン が多い: "name":"age": 等のキーが繰り返し出現。Dictionary = 「これらの共通トークンを事前に入れた参照資料」。圧縮時に参照を Dictionary に向ければ非常に短い符号になる。

13.3 学習プロセス

zstd --train samples/*.json --maxdict=110K -o dict
  1. サンプルファイルを読み込む。
  2. 最もよく出る部分文字列 を統計的に抽出。
  3. 上位を Dictionary に含める。
  4. Dictionary ファイルを出力。

13.4 使い方

zstd -D dict input.json -o output.zst

Dictionary ファイルは encoder と decoder の両方 が保持する必要がある。共有が必要。

13.5 性能

7 倍差。大量の小さなメッセージ転送で必須。

13.6 ユースケース

Facebook はこの手法で petabyte 規模の保存コストを削減。


14. 実戦例

14.1 HTTP サーバー

Accept-Encoding: gzip, br, zstd

Response:
Content-Encoding: zstd

Nginx:

http {
    zstd on;
    zstd_comp_level 3;
    zstd_types text/html text/css application/javascript application/json;
}

(zstd モジュールが必要。既定 Nginx は gzip。) 静的ファイル はビルド時に事前圧縮 (.br, .gz ファイル) -> ランタイム CPU を節約。

14.2 Kafka

compression.type=zstd

Producer がバッチを圧縮。既定 3 レベルでテキストメッセージが 3-5 倍 削減。Broker は圧縮バッチを そのまま保存・転送 -> CPU 効率が高い。

14.3 Kubernetes コンテナイメージ

OCI イメージレイヤーは通常 gzip。zstd に移行中:

docker build --compression=zstd .

Pull 時間 30-50% 短縮。大きなイメージ (ML モデル) に有効。

14.4 バックアップ

tar -cf - /data | zstd -19 --long > backup.tar.zst

--long で大 window を使い、ファイル間の重複も除去。Rsync + zstd は従来の gzip 組み合わせより 10-30% 速く小さい。

14.5 DB

RocksDB:

options.compression = kZstdCompression;
options.bottommost_compression = kZstdCompression;
options.compression_opts.level = 3;

L0-L4 は LZ4 (速い)、L5-L6 は zstd (高圧縮)。Tiered compression。

ClickHouse:

CREATE TABLE events (
    ...
) ENGINE = MergeTree
SETTINGS
    index_granularity = 8192;

ALTER TABLE events MODIFY COLUMN data CODEC(ZSTD(3));

カラム別に異なる codec。


15. 現代のトレンド

15.1 Asymmetric Speed

Decode >> Encode の速度不均衡を活用: 1 度圧縮、数千回解凍 (Web、CDN、画像)。Encoder に時間投資 して decoder を速く。Brotli -11、zstd -19。

15.2 Hardware Acceleration

大規模サービスの主要投資領域。

15.3 ML ベース

Google DeepMind の実験: LLM ベースの圧縮。モデルが「次のトークンを予測」し差分だけ保存。画像/テキストで 5-10 倍圧縮。ただし遅く GPU が必要 — 実用的ではない。特殊用途 (genome, 科学データ) で関心。

15.4 Lossy Text?

「多少の誤りを許容する」テキスト圧縮の研究中。自然言語の情報理論限界は 1-1.5 bit/char だが LLM が下げる可能性。学術段階。

15.5 次世代 entropy coder?

ANS から 10 年。Pelican、rANS 変種などが実験中。ただし ANS が十分に良く、主流交代はしばらく来そうにない。


16. よくある質問

Q: すでに圧縮されたファイルをもう一度圧縮すると?

A: 効果ほぼなし。JPEG、MP3、ZIP、既に gzip されたファイル等。通常 1% 未満の節約、むしろ大きくなることもある (メタデータ)。

Q: Solid 圧縮 vs ファイル別圧縮?

A: Solid (全体を 1 つの stream): ファイル間の重複を活用、比率が良い。欠点: 1 つ取り出すのに全体解凍。ファイル別: 独立、random access が速い。欠点: 共有重複の損失。ZIP はファイル別、tar.gz / tar.zst / 7z は solid。

Q: 最大効率の組み合わせは?

A: LZMA / zstd --long どちらも GB 規模の window で大ファイル間の重複を活用。

Q: 暗号化との組み合わせは?

A: 圧縮 -> 暗号化 の順。逆は暗号化済みデータがランダムなので圧縮不可。注意: CRIME/BREACH のような長さベース攻撃。HTTPS で機微データ + 圧縮が混在すると危険。

Q: Streaming サポート?

A: Zstd、Brotli、gzip すべて streaming API あり。入力を一度に持たなくても圧縮可能。


17. 1 枚まとめ

+------------------------------------------------------+
|          Compression Cheat Sheet                     |
+------------------------------------------------------+
| 基本原理:                                            |
|   2 段: LZ (重複除去) + Entropy (統計)               |
|                                                      |
| LZ ファミリー:                                       |
|   LZ77 (Sliding Window, back-reference)              |
|   LZSS (最小 match 長)                               |
|   LZ78/LZW (明示 Dictionary, 非推奨)                 |
|                                                      |
| Entropy Coding:                                      |
|   Huffman (1952): 整数 bit, 高速                     |
|   Arithmetic (1970s): 実数 bit, 低速, 特許           |
|   ANS/FSE (2009): Arithmetic 品質 + Huffman 速度     |
|                                                      |
| 主要アルゴリズム:                                    |
|   Deflate (1993): LZ77 + Huffman                     |
|   LZ4 (2011): LZ77 のみ, 超高速                      |
|   Zstandard (2016): LZ77 + FSE                       |
|   Brotli (2015): 静的 Dictionary + context           |
|   LZMA (1998): LZ77 + Markov + Range                 |
|                                                      |
| 速度 vs 比率:                                        |
|   LZ4/Snappy: 高速, 低比率                           |
|   gzip -1: 高速, 中                                  |
|   zstd -3: バランス (既定推奨)                       |
|   gzip -9: 低速, 良比率                              |
|   zstd -19: 低速, より良い比率                       |
|   brotli -11: 低速, Web 最適                         |
|   xz -9: 非常に低速, 最良比率                        |
|                                                      |
| 用途別:                                              |
|   リアルタイム: LZ4                                  |
|   汎用: zstd -3                                      |
|   バックアップ: zstd -19 または xz                   |
|   Web: brotli                                        |
|   小メッセージ: zstd + Dictionary                    |
|                                                      |
| Dictionary Training:                                 |
|   zstd --train                                       |
|   小メッセージで 10-100 倍改善                       |
|   Kafka, HTTP API, NoSQL に有効                      |
|                                                      |
| 加速:                                                |
|   SIMD (libdeflate, zstd)                            |
|   ハードウェア (Intel QAT)                           |
|   GPU                                                |
|                                                      |
| 注意:                                                |
|   圧縮済みのものは再圧縮不可                         |
|   暗号化の前に圧縮                                   |
|   CRIME/BREACH 注意 (HTTPS)                          |
+------------------------------------------------------+

18. クイズ

Q1. 可逆圧縮がほぼ「2 段」である理由は?

A. 2 種類の冗長性をそれぞれ別の方法で解決するため。(1) 構造的冗長性: "ABCDEFABCDEF" のようにシーケンスが反復する場合 — LZ77 系の back-reference が完璧。数バイトで長い反復を参照。だがこの段階では単一記号の統計偏りは扱えない。(2) 統計的偏り: "e" (21%)、"a" (8%)、"z" (0.1%) のような不均衡分布 — Entropy coding (Huffman/ANS) が頻出記号に短符号を割り当て。2 段を分離することで各々を最適化可能。現代の compressor (Deflate/Zstd/Brotli) はすべてこのパターン。「一度にすべて処理」する方法 (PPM, context mixing) も理論的にはあるが実装複雑度と速度の問題で実用的でない。分割統治の教科書的事例。

Q2. Huffman coding の根本的限界は?

A. 最低 1 bit/symbol という整数制約。Huffman は各記号に prefix-free の整数 bit 長符号を割り当て。確率 50% なら理想 1 bit (完璧)、25% なら 2 bit (完璧)。だが 確率 90% なら理想 ~0.15 bit が必要なのに Huffman は最低 1 bit — 85% の損失。テキストの空白、'e' のような高頻度記号がこのケース。Shannon エントロピー限界に到達できない。Arithmetic coding と ANS は「1 記号に 0.15 bit」を数学的に表現 — 「複数記号をまとめて整数 bit に pack」。Huffman 比で 5-15% 良い比率。1952 年から 60 年間 Huffman が主流だった理由は速度と特許自由 — その後 ANS (2009) が両問題を同時解決。現代の compressor (zstd, LZFSE) が Huffman から ANS へ移った背景。

Q3. ANS が「game changer」と呼ばれる理由は?

A. Arithmetic coding の圧縮率を Huffman の速度で達成。30 年間「Huffman は速いが suboptimal、Arithmetic は optimal だが遅く特許」という膠着状態。ANS (2009, Jarek Duda) は新しい数学的アプローチで両方を同時解決: (1) 圧縮率: Arithmetic とほぼ同等、Huffman より 5-10% 良い、(2) 速度: Huffman より 1.5-2 倍速い (shift + lookup のみ、浮動小数/除算なし)、(3) 特許自由: Duda が意図的に公開。商用採用順: LZFSE (Apple 2015) -> Zstd (Facebook 2016) -> AV1 (2018)。現代の compressor で「Huffman の代わりに FSE/ANS」が標準に。「速さと良さのどちらか」を選ばざるを得なかった classic CS trade-off が崩れた稀有な事例。なぜもっと早く発見されなかったかは CS 史の謎。

Q4. Zstandard の Dictionary training が解決する問題は?

A. 小さなメッセージに内部重複がない問題。通常の compressor (gzip, LZ4) は入力ファイル内の反復のみを見つける。100 バイトの JSON {"name":"Alice","age":30} のようなメッセージには内部にほぼ反復がない -> 圧縮率 ~5% または 逆効果 (メタデータでむしろ大きくなる)。だが数千個の似た JSON を集めて見ると "name":, "age": のキーが 非常に反復的。Dictionary training: (1) サンプルファイルから最もよく出る部分文字列を抽出 -> ~10 KB の Dictionary、(2) この Dictionary を encoder と decoder 両方に配布、(3) 圧縮時に Dictionary を「仮想 prefix」として使用 -> 小さなメッセージも 70% 以上削減。実測: 100 バイトの JSON が通常の zstd で 90 バイト -> Dictionary zstd で 30 バイト (7 倍差)。Facebook, Kafka, HTTP API がこの手法でメッセージ payload を 50-80% 削減。欠点: Dictionary 共有が必要、他のデータタイプには効果なし。「圧縮は相関を活用する」原則を追加の context (Dictionary) で拡張したもの。

Q5. LZ4 が gzip より圧縮率が低いのに DB で好まれる理由は?

A. 解凍速度が DB 性能のボトルネックだから。DB はディスクからデータを読み 即座に使う 必要がある。Read path: disk read -> decompress -> query。gzip decompress (~400 MB/s) が SSD read (~5 GB/s) の 10 倍遅いと CPU が I/O に追いつけない。LZ4 は 3-5 GB/s decompress — SSD 速度に近い。圧縮率は gzip 3x に対し 2x で保存領域を多く使うが、読み取り性能が 10 倍速い。リアルタイムクエリではこのトレードオフが重要。RocksDB の tiered compression 戦略: よく読まれる L0-L1 は LZ4、稀に読まれる L5-L6 は zstd。「ホットデータは速い圧縮、コールドデータは高比率」。Cassandra も同様。「圧縮率が最優先ではなく パイプライン全体のスループット」が核心 — 個別段階の最適化と系全体の最適化が異なるという教訓。

Q6. Brotli が HTTP で Zstd より良い理由は?

A. 静的 Dictionary 内蔵 + HTML/CSS/JS チューニング。Brotli は 120 KB の 内蔵 Dictionary を持つ — 英単語、HTML タグ、CSS 属性、JavaScript キーワードが事前に含まれる。Web ページ圧縮時にこの Dictionary を「仮想 prefix」として使用 -> 小さなページも非常に圧縮。Zstd は内蔵 Dictionary がないので Dictionary なしで Web コンテンツではやや劣る。実測: 10 MB の Web コンテンツで brotli -11 が zstd -19 より 5-10% 小さい。さらに Brotli は context modeling が精緻 — literal 周辺の context を考慮した Huffman tree 選択。欠点: Brotli の圧縮が遅く ビルド時事前圧縮 (*.html.br ファイル) が必要。ランタイム圧縮は zstd が依然優位。現代 Web stack: 静的ファイルは Brotli 事前圧縮 (.br)、動的応答は gzip または zstd。Cloudflare のような CDN がエッジでこれを管理。「同じ問題でも使用パターンにより最適アルゴリズムが異なる」例。

Q7. すでに圧縮されたファイル (JPEG, MP3, ZIP) を再圧縮しても効果がない理由は?

A. 圧縮済みデータは統計的にランダムに近い。圧縮の基本原理が「重複除去 + 偏り活用」だが、よく圧縮されたデータは定義上 重複がほぼなく分布も均一。LZ77 は見つけるべき back-reference がなく (全シーケンスが一意)、Huffman/ANS は活用すべき偏りがない (全記号がほぼ等確率)。Shannon の限界に近く、これ以上削れない。再圧縮結果: (1) ~0-1% 節約 (ノイズレベル)、(2) メタデータオーバーヘッドで むしろ増加、(3) CPU の無駄。例外: (a) 圧縮済みファイル間の重複 — 同ファイルを複数回圧縮した tar で solid 圧縮なら一部節約、(b) lossy -> lossless 再エンコード — JPEG を PNG 変換後圧縮 (別物になる)。実務ルール: MIME タイプが既に圧縮されたもの (image/jpeg, video/mp4, application/zip) は HTTP compression skip。Nginx の gzip_types でこれらを除外するのはこのため。「圧縮は関連性 (redundancy) を糧とする、ランダムでは飢える」。


19. 学習リソース

論文:

書籍:

ブログ:

ツール:

ソース:


この記事が役に立ったら、以下の関連記事もどうぞ:

コメント

まだコメントはありません。

ログインするとコメントできます