Wednesday, June 4, 2008

Compression shoot out

I had some time on my hands the other day and a 2.9/4 GiB debian lenny ext3 filesystem sitting rather idly on one of my hard drives (This fs serves as a backup OS in case my bleeding edge gentoo bellies up on me). This fs includes Xorg, Firefox, Xfce4, GNOME among other installed packages. Having just observed the coreutils distribution switch to lzma I was really curious about lzma's performance. A file system filled with linux applications and data was a good candidate for compression testing. I decided to round up gzip, bzip2, lha, zip, rar, lzma and lrzip to see what they were made of.

I copied the blocks to a file using dd, loop mounted the file and started copying from /dev/zero to a file on the loop mounted fs so as to prepare the unused blocks with redundant data. Eventually the dd command stopped with a file system full warning, so I synced the fs and deleted the zero stuffed file. I unmounted the looped back fs and started compressing...

Several CPU hours later I had an impressive amount of digits which I have decided to share with you through this blog. Here are the hard numbers:

Original file: __4,293,563,904 (3.999 GiB) (4096 MiB down to nearest cylinder boundary)
Zero file size: _1,150,640,128 (1.072 GiB)
Net fs size: ____3,142,923,776 (2.927 GiB) (This number is used as the uncompressed size)
fs usage per df: 3,065,671,680 (2.856 GiB)
ext3fs overhead: ___77,252,096 (2.458 %)

compressor _________size ______________ratio__________CPU usage
none_______3,142,923,776_(2.9271 GiB)_1.0000

gzip_-9____1,177,245,158_(1.0964 GiB)_2.6697______593s (sys 24s)

zip_-9_____1,177,245,231_(1.0964 GiB)_2.6697______554s (sys 25s)

lha_-o7____1,152,406,262_(1.0733 GiB)_2.7273____1,492s (sys 39s)

bzip2_-9___1,082,698,303_(1.0083 GiB)_2.9029____2,316s (sys 25s)

rar_-m5______942,002,518_(0.8773 GiB)_3.3364____3,481s (sys 30s)

lzma_-9______871,912,252_(0.8120 GiB)_3.6046___10,334s (sys 23s, wall 10,471s)

lrzip_-w9____849,062,862_(0.7908 GiB)_3.7016____4,483s (sys 35s, wall 7,000s
)

(Sorry about the formatting...)

Wall clock times are not much different from user times except for lzma and lrzip. This is because these beasts use large windows which results in swapping.

Observations:

  • gzip and Zip use the same algorithm, ie. PKZIP deflate. The file size difference is in headers. Zip compression is noticeably faster.
  • lrzip spent 42 minutes (!) swapping. I need more RAM!
  • There is an almost perfect correlation between CPU time spent and compression ratio achieved. The exception is that lrzip is a lot quicker than lzma (which lrzip uses, incidently) at highest settings.
  • It would be interesting to measure RAM usage during compression, but I haven't found a simple way to do that.
  • It would be interesting to benchmark decompression too. To be done.

Bench mark host and contestants information:

AMD Athlon XP 2400+ @ 2GHz,256 kB L2
1 GB DDR PC2700 @ 266 MHz
Linux 2.6.24

  • gzip 1.3.12
  • Zip 2.32
  • LHa 1.14i-ac20050924p1
  • bzip2 1.0.5
  • RAR 3.71
  • LZMA SDK 4.32.6
  • lrzip 0.23
All built on host with gcc 4.2.3 using CFLAGS="-march=athlon-xp -O2 -pipe".