11 ポイント 投稿者 xguru 2021-03-16 | 4件のコメント | WhatsAppで共有
  • Python の tarfile 関数で作ったファイルより、macOS の tar で作ったファイルのほうが 15 倍大きくなった

  • 原因: BSD/GNU tar は圧縮ファイル内にファイルを順不同で入れるため、ファイルの種類によっては圧縮率が下がることがある

→ Python の tarfile 関数はデフォルトでソートされる

  • GNU tar の場合、--sort オプションで name / inode 順に並べて格納できる → ソートを適用すると同じ圧縮率になる

4件のコメント

 
deadcat 2021-03-16

少し理解できないのですが、並べ替えを適用すると、なぜ圧縮率が変わるのでしょうか。個々のファイルごとの圧縮率は同じはずですよね。

 
dalinaum 2021-03-22

使用されているアルゴリズムは Deflate です。これは、以前に圧縮で使用した内容をスライディングウィンドウに保持します。今回 10 バイトを処理したなら、スライディングウィンドウには現在処理した 10 バイトが末尾に追加される形で管理され、スライディングウィンドウのサイズは固定です。

スライディングウィンドウに入っている内容と同じ内容が見つかると、代わりに LLD (Literal, Length, Distance) を記録して圧縮する方式です。Distance はスライディングウィンドウのどこから同じ内容なのか、Length はスライディングウィンドウ内で同じ内容の長さ、Literal は一致しない最初の文字です。

Deflate では、スライディングウィンドウに何が入っているかが重要なため、直前に類似した内容を見たかどうかが重要であり、類似したファイルを見ていれば、よりうまく圧縮できる可能性があります。

 
dalinaum 2021-03-22

どのように圧縮されるかは、以下のスライドを参照してください。(gzipもDeflateベースです。)

https://speakerdeck.com/dalinaum/…

 
xguru 2021-03-16

同じフォルダ内で同じ名前/似た名前を持つファイルは内容も似ているので圧縮率が高くなるはずですが、

圧縮時にそうした類似性を探す範囲はそれほど広くないため、ファイルを並べ替えると似たもの同士が集まり、圧縮されやすくなる可能性が高い、という話だと思います。