tar コマンドではアーカイブと同時に圧縮することが出来ます。昔は gzip しか使えませんでしたが、今は bzip2/xz も使うことが出来ます。そこで、それぞれの圧縮方法で実際にどれくらい圧縮効率と圧縮/展開時間が違うのか比較してみました。
実験環境
実験した環境は FreeBSD 11.4-RELEASE-p4 で、tar コマンドのバージョンは 3.4.2 です。
使用したデータはウィキペディア日本語版のデータベースダンプです。2020年11月1日版で 13584231059 バイト(13 GiB)ありました。
$ curl -O https://dumps.wikimedia.org/jawiki/latest/jawiki-latest-pages-articles.xml.bz2
$ bzip2 -d jawiki-latest-pages-articles.xml.bz2
$ ls -l jawiki-latest-pages-articles.xml
-rw-r--r-- 1 saoyagi2 staff 13584231059 11月 11 09:48 jawiki-latest-pages-articles.xml
実験
gzip
$ /usr/bin/time tar czf jawiki-latest-pages-articles.xml.tar.gz jawiki-latest-pages-articles.xml
852.37 real 826.38 user 24.54 sys
$ ls -l jawiki-latest-pages-articles.xml.tar.gz
-rw-r--r-- 1 saoyagi2 staff 4366160632 11月 12 12:11 jawiki-latest-pages-articles.xml.tar.gz
$ /usr/bin/time tar xf jawiki-latest-pages-articles.xml.tar.gz
175.45 real 82.09 user 20.99 sys
bzip2
$ /usr/bin/time tar cjf jawiki-latest-pages-articles.xml.tar.bz2 jawiki-latest-pages-articles.xml
2313.50 real 2289.61 user 21.92 sys
$ ls -l jawiki-latest-pages-articles.xml.tar.bz2
-rw-r--r-- 1 saoyagi2 staff 3235179785 11月 12 12:53 jawiki-latest-pages-articles.xml.tar.bz2
$ /usr/bin/time tar xf jawiki-latest-pages-articles.xml.tar.bz2
1073.77 real 1044.34 user 27.68 sys
xz
$ /usr/bin/time tar cJf jawiki-latest-pages-articles.xml.tar.xz jawiki-latest-pages-articles.xml
13596.21 real 13561.03 user 28.69 sys
$ ls -l jawiki-latest-pages-articles.xml.tar.xz
-rw-r--r-- 1 saoyagi2 staff 2787826328 11月 12 16:57 jawiki-latest-pages-articles.xml.tar.xz
$ /usr/bin/time tar xf jawiki-latest-pages-articles.xml.tar.xz
350.36 real 327.34 user 21.27 sys
まとめと考察
圧縮方法 | 圧縮時間(user + sys) | 展開時間(user + sys) | 圧縮後サイズ | 圧縮率 |
---|---|---|---|---|
gzip | 850.92 秒 | 103.08 秒 | 4366160632 バイト(4.1 GiB) | 32.14% |
bzip2 | 2311.53 秒 | 1072.02 秒 | 3235179785 バイト(3.0 GiB) | 23.81% |
xz | 13589.72 秒 | 348.61 秒 | 2787826328 バイト(2.6 GiB) | 20.52% |
傾向としては、
- 圧縮時間は gzip < bzip2 < xz
- 展開時間は gzip < xz < bzip2
- 圧縮率は xz < bzip2 < gzip
となりました。もちろんファイルの内容によっていずれも変わってきますので、必ずこの順位になるとは限りません。また、tar のオプションではなく各圧縮コマンドを独立して使用する場合には圧縮率のオプションを指定できますので、さらに傾向が変わる可能性があります。(圧縮レベル指定についての追記参照)
この傾向から判断するとすると
- gzip - そこそこ圧縮率で圧縮時間・展開時間とも最速。ファーストチョイスとして最適。
- bzip2 - xz よりも短い圧縮時間で gzip よりも高圧縮率を得られる。展開は遅い。長期保存するログなど、めったに展開しない用途に向いている。
- xz - 圧縮には膨大な時間がかかるが展開時間は高速で圧縮率も良い。一度だけ圧縮して何度も展開されるファイル配布などの用途に向いている。
といったところでしょうか。実験を始める前は gzip はそろそろ退役してよいのかなと思っていたのですが、なんのなんのファーストチョイスとしては今でも間違いなさそうです。
圧縮レベル指定についての追記(2020.11.23)
環境変数やオプションによって tar コマンド単体でも圧縮レベルを指定できることを知りました。例えば以下のようにします。
$ export GZIP=-9
$ tar czf jawiki-latest-pages-articles.xml.tar.gz jawiki-latest-pages-articles.xml
$ export BZIP2=-9
$ tar cjf jawiki-latest-pages-articles.xml.tar.bz2 jawiki-latest-pages-articles.xml
$ export XZ_OPT=-9
$ tar cJf jawiki-latest-pages-articles.xml.tar.xz jawiki-latest-pages-articles.xml
ただし、gzip の最近のバージョン(1.8以降?)では GZIP 環境変数は廃止されたそうなのですが、手元の Ubuntu 20.04 LTS 環境では gzip: warning: GZIP environment variable is deprecated; use an alias or script
とメッセージは出るものの、まだ GZIP 環境変数は機能していました。gzip のバージョンは 1.10 でした。
FreeBSD の tar では GZIP のみならず BZIP2 も XZ_OPT も効かなくなっていました。FreeBSD では代わりに compression-level オプションで圧縮レベルを指定できます。
$ tar czf jawiki-latest-pages-articles.xml.tar.gz --options gzip:compression-level=9 jawiki-latest-pages-articles.xml
$ tar cjf jawiki-latest-pages-articles.xml.tar.bz2 --options bzip2:compression-level=9 jawiki-latest-pages-articles.xml
$ tar cJf jawiki-latest-pages-articles.xml.tar.xz --options xz:compression-level=9 jawiki-latest-pages-articles.xml