Skip to content

Commit

Permalink
deflate_compress: use lazy2 compressor for levels 8-9
Browse files Browse the repository at this point in the history
Instead of switching directly from the lazy compressor at level 7 to the
near-optimal compressor at level 8, use the lazy2 compressor at levels
8-9 and don't switch to near-optimal until level 10.

This avoids poor compression ratio and bad performance (both
significantly worse than level 7, and significantly worse than zlib) at
levels 8-9 on data where the near-optimal compressor doesn't do well
until the parameters are cranked up.

On data where the near-optimal compressor *does* do well, this change
worsens the compression ratio of levels 8-9, but also speeds them up a
lot, thus positioning them similarly vs. zlib as the lower levels (i.e.
much faster and slightly stronger, rather than slightly faster and much
stronger).  The difference between levels 9 and 10 is increased, but
that's perhaps the least bad place to have a discontinuity.

Resolves #85
  • Loading branch information
ebiggers committed Dec 31, 2021
1 parent ae6176e commit 5d6c650
Showing 1 changed file with 17 additions and 25 deletions.
42 changes: 17 additions & 25 deletions lib/deflate_compress.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@

/*
* By default, the near-optimal parsing algorithm is enabled at compression
* level 8 and above. The near-optimal parsing algorithm produces a compression
* ratio significantly better than the greedy and lazy algorithms implemented
* here, and also the algorithm used by zlib at level 9. However, it is slow.
* level 10 and above. The near-optimal parsing algorithm produces a
* compression ratio significantly better than the greedy and lazy algorithms
* implemented here, and also the algorithm used by zlib at level 9. However,
* it is slow.
*/
#define SUPPORT_NEAR_OPTIMAL_PARSING 1

Expand Down Expand Up @@ -2789,7 +2790,7 @@ libdeflate_alloc_compressor(int compression_level)
return NULL;

#if SUPPORT_NEAR_OPTIMAL_PARSING
if (compression_level >= 8)
if (compression_level >= 10)
size += sizeof(c->p.n);
else if (compression_level >= 1)
size += sizeof(c->p.g);
Expand Down Expand Up @@ -2849,19 +2850,20 @@ libdeflate_alloc_compressor(int compression_level)
c->max_search_depth = 100;
c->nice_match_length = 130;
break;
#if SUPPORT_NEAR_OPTIMAL_PARSING
case 8:
c->impl = deflate_compress_near_optimal;
c->max_search_depth = 12;
c->nice_match_length = 20;
c->p.n.num_optim_passes = 1;
c->impl = deflate_compress_lazy2;
c->max_search_depth = 300;
c->nice_match_length = DEFLATE_MAX_MATCH_LEN;
break;
case 9:
c->impl = deflate_compress_near_optimal;
c->max_search_depth = 16;
c->nice_match_length = 26;
c->p.n.num_optim_passes = 2;
#if !SUPPORT_NEAR_OPTIMAL_PARSING
default:
#endif
c->impl = deflate_compress_lazy2;
c->max_search_depth = 600;
c->nice_match_length = DEFLATE_MAX_MATCH_LEN;
break;
#if SUPPORT_NEAR_OPTIMAL_PARSING
case 10:
c->impl = deflate_compress_near_optimal;
c->max_search_depth = 30;
Expand All @@ -2874,24 +2876,14 @@ libdeflate_alloc_compressor(int compression_level)
c->nice_match_length = 80;
c->p.n.num_optim_passes = 3;
break;
case 12:
default:
c->impl = deflate_compress_near_optimal;
c->max_search_depth = 100;
c->nice_match_length = 133;
c->p.n.num_optim_passes = 4;
break;
#else
case 8:
c->impl = deflate_compress_lazy;
c->max_search_depth = 150;
c->nice_match_length = 200;
break;
default:
c->impl = deflate_compress_lazy;
c->max_search_depth = 200;
c->nice_match_length = DEFLATE_MAX_MATCH_LEN;
break;
#endif
#endif /* SUPPORT_NEAR_OPTIMAL_PARSING */
}

deflate_init_offset_slot_fast(c);
Expand Down

0 comments on commit 5d6c650

Please sign in to comment.