Quicklz is known as the world's fastest compression library, and is also an open-source compression library, which complies with the GPL 1, 2 or 3 protocol.
On the official quicklz website, we have a test on quicklz:
| Library |
Level |
Compressed Size |
Compression MByte/s |
Decompression MByte/s |
| Quicklz C 1.5.0 |
1 |
47.9% |
308 |
358 |
| Quicklz C 1.4.0 |
1 |
47.9% |
272 |
332 |
| Quicklz C 1.4.0 |
2 |
42.3% |
131 |
309 |
| Quicklz C 1.4.0 |
3 |
40.0% |
31 |
516 |
| Quicklz C #1.4.0 |
1 |
47.9% |
133 |
132 |
| Quicklz Java 1.4.0 |
1 |
47.9% |
127 |
95 |
| Lzf 3.1 |
UF |
54.9% |
204 |
396 |
| Lzf 3.1 |
VF |
51.9% |
193 |
384 |
| Fastlz 0.1.0 |
1 |
53.0% |
173 |
442 |
| Fastlz 0.1.0 |
2 |
50.7% |
167 |
406 |
| Lzo 1x2.02 |
1 |
48.3% |
169 |
434 |
| Z lib 1.22 |
1 |
37.6% |
55 |
234 |
Here, I also conduct a comparison test on quicklz and zlib to see if it is so fast and so good.
Quicklz has a front-end program named qpress, which can be downloaded from the official quicklz website for testing. Zlib does not have a front-end program, so you have to write one by yourself.
The zlib test program can be rewritten based on an example in the zlib source code, as follows:
# Include <zlib. h> <br/> # include <stdio. h> <br/> # include <string. h> <br/> # include <assert. h> <br/> # include <zconf. h> <br/> # define chunk 16384 <br/> int def (File * Source, file * DEST, int level) <br/>{< br/> int ret, flush; <br/> unsigned have; <br/> z_stream STRM; <br/> char in [chunk]; <br/> Char out [chunk]; <br/>/* allocate deflate state */<br/> STRM. zarloc = z_null; <br/> STRM. zfree = z_null; <br/> STRM. opaque = z_null; <br/> ret = deflateinit (& STRM, level); <br/> If (Ret! = Z_ OK) <br/> return ret; <br/>/* compress until end of file */<br/> do {<br/> STRM. avail_in = fread (in, 1, Chunk, source); <br/> If (ferror (source) {<br/> (void) deflateend (& STRM ); <br/> return z_errno; <br/>}< br/> flush = feof (source )? Z_finish: z_no_flush; <br/> STRM. next_in = (bytef *) in; <br/>/* Run deflate () on input until output buffer not full, finish <br/> compression if all of source has been read in */<br/> do {<br/> STRM. avail_out = chunk; <br/> STRM. next_out = (bytef *) out; <br/> ret = deflate (& STRM, flush);/* No bad return value */<br/> assert (Ret! = Z_stream_error);/* State not clobbered */<br/> have = chunk-STRM. avail_out; <br/> If (fwrite (Out, 1, have, DEST )! = Have | ferror (DEST) {<br/> (void) deflateend (& STRM); <br/> return z_errno; <br/>}< br/>}while (STRM. avail_out = 0); <br/> assert (STRM. avail_in = 0);/* all input will be used */<br/>/* done when last data in file processed */<br/>} while (flush! = Z_finish); <br/> assert (ret = z_stream_end ); /* stream will be complete */<br/>/* clean up and return */<br/> (void) deflateend (& STRM); <br/> return z_ OK; <br/>}< br/>/* decompress from file source to file DEST until stream ends or EOF. <br/> Inf () returns z_ OK on success, z_mem_error if memory cocould not be <br/> allocated for processing, z_data_error if the deflate data is <br/> invalid or in Complete, z_version_error if the version of zlib. H and <br/> the version of the library linked do not match, or z_errno if there <br/> is an error reading or writing the files. */<br/> int Inf (File * Source, file * DEST) <br/>{< br/> int ret; <br/> unsigned have; <br/> z_stream STRM; <br/> char in [chunk]; <br/> Char out [chunk]; <br/>/* allocate inflate state */<br/> STRM. zarloc = z_null; <br/> Str M. zfree = z_null; <br/> STRM. opaque = z_null; <br/> STRM. avail_in = 0; <br/> STRM. next_in = z_null; <br/> ret = inflateinit (& STRM); <br/> If (Ret! = Z_ OK) <br/> return ret; <br/>/* decompress until deflate stream ends or end of file */<br/> do {<br/> STRM. avail_in = fread (in, 1, Chunk, source); <br/> If (ferror (source) {<br/> (void) inflateend (& STRM ); <br/> return z_errno; <br/>}< br/> If (STRM. avail_in = 0) <br/> break; <br/> STRM. next_in = (bytef *) in; <br/>/* Run inflate () on input until output buffer not full */<br/> do {<br/> Str M. avail_out = chunk; <br/> STRM. next_out = (bytef *) out; <br/> ret = inflate (& STRM, z_no_flush); <br/> assert (Ret! = Z_stream_error);/* State not clobbered */<br/> switch (RET) {<br/> case z_need_dict: <br/> ret = z_data_error; /* and fall through */<br/> case z_data_error: <br/> case z_mem_error: <br/> (void) inflateend (& STRM ); <br/> return ret; <br/>}< br/> have = chunk-STRM. avail_out; <br/> If (fwrite (Out, 1, have, DEST )! = Have | ferror (DEST) {<br/> (void) inflateend (& STRM); <br/> return z_errno; <br/>}< br/>}while (STRM. avail_out = 0); <br/>/* done when inflate () says it's done */<br/>} while (Ret! = Z_stream_end); <br/>/* clean up and return */<br/> (void) inflateend (& STRM); <br/> return ret = z_stream_end? Z_ OK: z_data_error; <br/>}< br/>/* report a zlib or I/O Error */<br/> void zerr (int ret) <br/>{< br/> fputs ("zpipe:", stderr); <br/> switch (RET) {<br/> case z_errno: <br/> If (ferror (stdin) <br/> fputs ("error reading stdin/N", stderr); <br/> If (ferror (stdout )) <br/> fputs ("error writing stdout/N", stderr); <br/> break; <br/> case z_stream_error: <br/> fputs ("invalid compression level/N", STD Err); <br/> break; <br/> case z_data_error: <br/> fputs ("invalid or incomplete deflate data/N", stderr ); <br/> break; <br/> case z_mem_error: <br/> fputs ("out of memory/N", stderr); <br/> break; <br/> case z_version_error: <br/> fputs ("zlib version mismatch! /N ", stderr); <br/>}< br/> int main (INT argc, char ** argv) <br/> {<br/> int ret; <br/>/* Do compression if no arguments */<br/> If (argc = 1) {<br/> // ret = def (stdin, stdout, z_default_compression); <br/> ret = def (stdin, stdout, z_best_speed ); <br/> If (Ret! = Z_ OK) <br/> zerr (RET); <br/> return ret; <br/>}< br/>/* Do decompression if-D specified */<br/> else if (argc = 2 & strcmp (argv [1], "-d") = 0) {<br/> ret = inf (stdin, stdout); <br/> If (Ret! = Z_ OK) <br/> zerr (RET); <br/> return ret; <br/>}< br/>/* otherwise, report usage */<br/> else {<br/> fputs ("zpipe usage: zpipe [-D] <source> DEST/N", stderr ); <br/> return 1; <br/>}< br/>
In the test, zilib adopts two compression methods, one is the fastest compression (z_best_speed) and the other is the default compression (z_default_compression), which can be seen in the main function.
Below is my NTFS partition in Linux, for a file with a FAT32 File System of 1 GB (this 1 GB file is the file I copied from a 1 GB FAT32 partition using winhex in Windows) results of the compressed test:
Quicklz adopts stable version 1.4.1 and zlib adopts stable version 1.2.3.
Quicklz (minimum compression zlib (default compression zlib (minimum compression rate)
Rate) version 1.4.1 rate) version 1.2.3
Time compressed real 2m5. 507 s
Real 1m23. 828 s
1,075,838,976 bytes
User 1m44. 079 s
User 1m2. 476 s
In 1 file (s) into sys 0m3. 164 s
Sys 0m2. 948 s
598,244,013 bytes
Real 0m29. 478 s
User 0m10. 209 s
Sys 0m2. 484 s
598244013 MB after compression
) 484103258 (462 m
) 510911735 (488 m
)
In the above test, we can see that the compression ratio of quicklz is lower than that of zlib, but the compression ratio is still acceptable, and the compression speed is indeed much faster than that of zlib. Quicklz compresses 1 GB of files with the lowest compression ratio. It takes 29.478 seconds to compress to 571 MB, while zlib uses 2 minutes and 5.507 seconds with the default compression ratio, compressed to 462 mb. zlib uses 1 minute and 23.828 seconds at the lowest compression ratio and compresses the data to 488 MB.
It seems that the compression speed of quicklz is not a waste of name.
Quicklz Official Website: http://www.quicklz.com/
Official website of zlib: http://www.zlib.net/