今回の結果:速度はzstd、合成ログの最小サイズはxz -6
16 MiBの合成ログでは、xz -6が今回の4設定で最小になりました。一方、zstd -3は圧縮・展開とも短時間で完了しました。gzip済みデータと疑似乱数データでは、どの設定もサイズ削減の効果はごく小さいか、かえって増えました。
この結果からは、頻繁に作成・展開するログのアーカイブにはzstd、処理時間を使って保管サイズを減らしたい場合にはxzを試す、という選び方が考えられます。ただし、単一環境・小規模な生成データでの結果です。実際のソースコード、VMイメージ、バックアップ全体でも同じ差になるとは限りません。
測定環境と比較条件
| 項目 | 条件 |
|---|---|
| 測定日 | 2026年10月26日(日本時間) |
| CPU | Intel Core i7-10750H @ 2.60 GHz(6コア・12スレッド) |
| OS | Fedora Linux 44、Linux 7.2.9-201.fc44.x86_64 |
| ツール | XZ Utils 5.8.2、zstd 1.5.7、Python 3.14.8 |
| 圧縮設定 | xz:-T1 -3と-T1 -6、zstd:--single-thread -3と--single-thread -9 |
| 繰り返し | 各データ・設定で圧縮と展開を1回予備実行し、その後3回測定。時間とピークRSSはそれぞれの中央値 |
| 計時 | Pythonのperf_counter_nsでプロセス起動から終了までを計測。GNU timeの起動とファイルI/Oを含む |
| メモリ | GNU timeの%Mで圧縮・展開プロセスのピークRSSを取得。計測用PythonやOSキャッシュのメモリは含まない |
| キャッシュ・出力先 | キャッシュ消去なし。圧縮は一時ファイルへ出力、展開は/dev/nullへ出力。fsyncは実行していない |
圧縮レベルの数字はツールごとの尺度です。xzの3とzstdの3が同じ圧縮強度を意味するわけではありません。圧縮はワーカー数を制限し、全コアを使う設定は今回測定していません。測定順序は各ラウンドでずらしましたが、CPU周波数・他の処理・温度は固定していません。
実データを持ち出さず、3種類のデータを生成
- 合成ログ:16 MiB。時刻、サービス名、URL、ステータス、待ち時間、疑似リクエストIDを持つテキスト。
- 疑似乱数:8 MiB。規則的なテキストとは異なる、縮みにくいデータの確認用。
- gzip済みログ:上記の合成ログをgzipレベル6で圧縮した2,760,680バイト。
乱数シードは20261026です。すべてテスト用に生成し、個人情報や実サービスのログは使用していません。疑似乱数は暗号学的な乱数ではありません。生成内容とSHA-256は測定結果JSONで確認できます。
今回は同じ単一ファイルを圧縮する処理を比較しています。tarで多数のファイルを収集する時間や、ディスクへ展開ファイルを書き出す時間は含まれません。
圧縮後サイズ・処理時間・メモリの実測結果
残存率は「圧縮後バイト数 ÷ 元のバイト数 × 100」です。低いほど小さく、100%を超えると元より増えています。時間とRSSも小さい方が負担を抑えられます。MiBは1,048,576バイトです。
合成ログ(元サイズ16,777,216バイト)
| 設定 | 圧縮後(バイト) | 残存率 | 圧縮(秒) | 展開(秒) | 圧縮RSS(MiB) | 展開RSS(MiB) |
|---|---|---|---|---|---|---|
| xz-3 | 2,757,192 | 16.434% | 1.799 | 0.092 | 29.9 | 6.2 |
| xz-6 | 2,197,488 | 13.098% | 5.897 | 0.100 | 84.9 | 10.2 |
| zstd-3 | 2,872,118 | 17.119% | 0.068 | 0.017 | 6.6 | 6.1 |
| zstd-9 | 2,710,752 | 16.157% | 0.276 | 0.017 | 18.1 | 8.1 |
疑似乱数(元サイズ8,388,608バイト)
| 設定 | 圧縮後(バイト) | 残存率 | 圧縮(秒) | 展開(秒) | 圧縮RSS(MiB) | 展開RSS(MiB) |
|---|---|---|---|---|---|---|
| xz-3 | 8,389,088 | 100.006% | 2.337 | 0.005 | 33.1 | 6.3 |
| xz-6 | 8,389,088 | 100.006% | 2.251 | 0.007 | 90.7 | 10.2 |
| zstd-3 | 8,388,814 | 100.002% | 0.008 | 0.005 | 7.1 | 5.9 |
| zstd-9 | 8,388,814 | 100.002% | 0.017 | 0.006 | 18.0 | 7.9 |
gzip済みログ(元サイズ2,760,680バイト)
| 設定 | 圧縮後(バイト) | 残存率 | 圧縮(秒) | 展開(秒) | 圧縮RSS(MiB) | 展開RSS(MiB) |
|---|---|---|---|---|---|---|
| xz-3 | 2,760,712 | 100.001% | 0.547 | 0.006 | 23.8 | 4.9 |
| xz-6 | 2,760,004 | 99.976% | 0.603 | 0.013 | 42.4 | 4.9 |
| zstd-3 | 2,760,760 | 100.003% | 0.007 | 0.004 | 6.9 | 5.9 |
| zstd-9 | 2,760,759 | 100.003% | 0.012 | 0.004 | 16.9 | 6.3 |
表の時間はプロセス起動を含むため、数ミリ秒の差は起動処理や測定時の負荷に左右されます。小さな差から細かな性能順位を決める用途には向きません。メモリは各回のピークRSSを集計した中央値であり、必要メモリの上限や全環境の動作保証ではありません。
結果から、どちらを選ぶか
頻繁に作る・何度も展開するなら、まずzstdを試す
合成ログではzstd -3が短い時間で処理できました。zstd -9はさらに小さくできますが、圧縮時間とメモリが増えています。定期的なログ保存や作業用アーカイブでは、まずレベル3で必要なサイズ削減が得られるか確認する方法があります。
保管サイズを優先するなら、xzも実データで比較する
合成ログのxz -6はzstd -3より小さくなりましたが、圧縮時間とピークRSSは大きくなりました。作成頻度が低い配布物や保管用データでは、この追加コストが見合うか判断します。xzの最高レベルやzstdの全レベルを調べた結果ではないため、方式そのものの圧縮率の限界は比較できません。
gzip済みファイルなどは、再圧縮の効果を先に確認する
今回のgzip済みログはxzレベル6でわずかに縮みましたが、処理時間に対して削減量は小さい結果でした。ZIPや動画なども一律に縮まるとは考えず、一部を試してから全量を処理します。
手元のファイルで比較するコマンド
次はGNU timeが/usr/bin/timeにあるLinux環境の例です。sample.logを手元の代表データに置き換えてください。初めて使う出力名を指定し、同名ファイルを上書きしないようにします。
# 元データを残して圧縮。%eは経過秒、%MはピークRSS(KiB)
/usr/bin/time -f 'elapsed_s=%e peak_rss_kib=%M' xz -T1 -6 -c sample.log > sample.log.xz
/usr/bin/time -f 'elapsed_s=%e peak_rss_kib=%M' zstd --single-thread -3 -c sample.log > sample.log.zst
# 展開して読み捨てる場合の時間とメモリ
/usr/bin/time -f 'elapsed_s=%e peak_rss_kib=%M' xz -d -c sample.log.xz > /dev/null
/usr/bin/time -f 'elapsed_s=%e peak_rss_kib=%M' zstd -d -c sample.log.zst > /dev/null
# 圧縮後の正確なバイト数
wc -c sample.log sample.log.xz sample.log.zst
この簡易例のGNU timeは秒を小数2桁で表示するため、短時間処理の精密比較には向きません。記事の表は後述のスクリプトで計測しています。どちらもストレージへの永続化完了までの性能を測るものではありません。
展開した内容が元と一致するかを確認する
# Bashの例:パイプ途中の失敗も終了ステータスへ反映
set -o pipefail
sha256sum sample.log
xz -d -c sample.log.xz | sha256sum
zstd -d -c sample.log.zst | sha256sum
3つのSHA-256値が一致することを確認します。今回の測定でも、12条件すべてで展開後のSHA-256が元データと一致することを確認しました。
生データと再実行用スクリプト
- 測定結果JSONをダウンロード:各回の時間・ピークRSS、中央値、サイズ、入力と復元後のSHA-256、環境情報。
- 測定用Pythonスクリプトをダウンロード:テストデータ生成、予備実行、3回測定、復元検証までを実行。
LinuxでPython、xz、zstd、GNU timeを用意し、ダウンロードしたスクリプトのある場所で実行します。一時データは一時ディレクトリに作成し、既存のユーザーデータは読み込みません。データ生成とツールのバージョンによって出力が変わる場合があります。
python3 benchmark-xz-zstd.py --output result.json
結果は実行した環境のものになります。異なるPCや大容量データでは差が変わるため、最終的には自分の用途に近いデータで選んでください。
参考資料
- XZ Utils公式マニュアル:圧縮設定、スレッド、標準入出力。
- zstd 1.5.7公式マニュアル:圧縮レベル、single-thread、展開。