[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    Re: [PATCH] gzip: add support for compression levels 4-9
From:       Denys Vlasenko <vda.linux () googlemail ! com>
Date:       2015-04-26 12:23:33
Message-ID: CAK1hOcP67+vOmNMEuFEHuAxqV=9dozW4nrggL9PRKD2soPj05w () mail ! gmail ! com
[Download RAW message or body]

Applied, thanks!

On Fri, Apr 24, 2015 at 7:41 PM, Aaro Koskinen <aaro.koskinen@iki.fi> wrote:
> Add support for compression levels 4-9.
>
> function                                             old     new   delta
> gzip_main                                            191     306    +115
> usage_messages                                     40461 40504     +43
> pack_gzip                                           1924    1907     -17
> ------------------------------------------------------------------------------
> (add/remove: 0/0 grow/shrink: 2/1 up/down: 158/-17)           Total: 141 bytes
>
> The rationale for this feature is that the current hardcoded 9 level
> is painfully slow with big files. Below are some examples when
> compressing a rootfs tarball (368.9M uncompressed) with different levels
> (gzip 1.6 compression time for comparison in parenthesis):
>
>                         compression time        compressed size
> Without the patch:      1m22.534s               152.0M
> With the patch, 9:      1m15.351s (1m7.419s)    152.0M (old bb default level)
>                 8:      0m46.763s (0m43.335s)   152.1M
>                 7:      0m28.519s (0m27.076s)   152.4M
>                 6:      0m22.960s (0m21.879s)   152.8M (gzip default level)
>                 5:      0m16.058s (0m14.740s)   153.9M
>                 4:      0m12.484s (0m11.167s)   156.4M
>
> If the compression level support is enabled, we make 6 the default
> as with gzip 1.6.
>
> Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> ---
>  archival/gzip.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 55 insertions(+), 1 deletion(-)
>
> diff --git a/archival/gzip.c b/archival/gzip.c
> index bc1f9c6..e6161e2 100644
> --- a/archival/gzip.c
> +++ b/archival/gzip.c
> @@ -62,14 +62,26 @@ aa:      85.1% -- replaced with aa.gz
>  //config:        1: larger buffers, larger hash-tables
>  //config:        2: larger buffers, largest hash-tables
>  //config:        Larger models may give slightly better compression
> +//config:
> +//config:config FEATURE_GZIP_LEVELS
> +//config:      bool "Enable compression levels"
> +//config:      default y
> +//config:      depends on GZIP
> +//config:      help
> +//config:        Enable support for compression levels 4-9. The default level
> +//config:        is 6 (without this option 9). If levels 1-3 are specified, 4
> +//config:        is used.
>
>  //applet:IF_GZIP(APPLET(gzip, BB_DIR_BIN, BB_SUID_DROP))
>  //kbuild:lib-$(CONFIG_GZIP) += gzip.o
>
>  //usage:#define gzip_trivial_usage
> -//usage:       "[-cfd] [FILE]..."
> +//usage:       "[-cfd" IF_FEATURE_GZIP_LEVELS("123456789") "] [FILE]..."
>  //usage:#define gzip_full_usage "\n\n"
>  //usage:       "Compress FILEs (or stdin)\n"
> +//usage:        IF_FEATURE_GZIP_LEVELS(
> +//usage:     "\n        -1..9   Compression level"
> +//usage:        )
>  //usage:     "\n       -d      Decompress"
>  //usage:     "\n       -c      Write to stdout"
>  //usage:     "\n       -f      Force"
> @@ -252,6 +264,8 @@ enum {
>   * input file length plus MIN_LOOKAHEAD.
>   */
>
> +#ifndef ENABLE_FEATURE_GZIP_LEVELS
> +
>         max_chain_length = 4096,
>  /* To speed up deflation, hash chains are never searched beyond this length.
>   * A higher limit improves compression ratio but degrades the speed.
> @@ -283,11 +297,23 @@ enum {
>   * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
>   * meaning.
>   */
> +#endif /* ENABLE_FEATURE_GZIP_LEVELS */
>  };
>
>
>  struct globals {
>
> +#ifdef ENABLE_FEATURE_GZIP_LEVELS
> +       unsigned _max_chain_length;
> +       unsigned _max_lazy_match;
> +       unsigned _good_match;
> +       unsigned _nice_match;
> +#define max_chain_length (G1._max_chain_length)
> +#define max_lazy_match   (G1._max_lazy_match)
> +#define good_match      (G1._good_match)
> +#define nice_match      (G1._nice_match)
> +#endif /* ENABLE_FEATURE_GZIP_LEVELS */
> +
>         lng block_start;
>
>  /* window position at the beginning of the current output block. Gets
> @@ -2161,6 +2187,22 @@ int gzip_main(int argc UNUSED_PARAM, char **argv)
>  #endif
>  {
>         unsigned opt;
> +#ifdef ENABLE_FEATURE_GZIP_LEVELS
> +       unsigned level;
> +       const struct {
> +               unsigned char good;
> +               unsigned char chain_shift;
> +               unsigned short lazy;
> +               unsigned short nice;
> +       } gzip_level_config[6] = {
> +               {4,   4,   4,  16}, /* Level 4 */
> +               {8,   5,  16,  32}, /* Level 5 */
> +               {8,   7,  16, 128}, /* Level 6 */
> +               {8,   8,  32, 128}, /* Level 7 */
> +               {32, 10, 128, 258}, /* Level 8 */
> +               {32, 12, 258, 258}, /* Level 9 */
> +       };
> +#endif /* ENABLE_FEATURE_GZIP_LEVELS */
>
>  #if ENABLE_FEATURE_GZIP_LONG_OPTIONS
>         applet_long_options = gzip_longopts;
> @@ -2171,6 +2213,11 @@ int gzip_main(int argc UNUSED_PARAM, char **argv)
>         if (opt & 0x18) // -d and/or -t
>                 return gunzip_main(argc, argv);
>  #endif
> +#ifdef ENABLE_FEATURE_GZIP_LEVELS
> +       /* Map 1..3 to 4 and make 6 a default. */
> +       level = ffs(opt >> (4 + IF_GUNZIP(2)) & 0x1ff);
> +       level = !level ? 6 : MAX(4, level);
> +#endif /* ENABLE_FEATURE_GZIP_LEVELS */
>         option_mask32 &= 0x7; /* ignore -q, -0..9 */
>         //if (opt & 0x1) // -c
>         //if (opt & 0x2) // -f
> @@ -2180,6 +2227,13 @@ int gzip_main(int argc UNUSED_PARAM, char **argv)
>         SET_PTR_TO_GLOBALS((char *)xzalloc(sizeof(struct globals)+sizeof(struct globals2))
>                         + sizeof(struct globals));
>
> +#ifdef ENABLE_FEATURE_GZIP_LEVELS
> +       max_chain_length = 1 << gzip_level_config[level - 4].chain_shift;
> +       good_match       = gzip_level_config[level - 4].good;
> +       max_lazy_match   = gzip_level_config[level - 4].lazy;
> +       nice_match       = gzip_level_config[level - 4].nice;
> +#endif /* ENABLE_FEATURE_GZIP_LEVELS */
> +
>         /* Allocate all global buffers (for DYN_ALLOC option) */
>         ALLOC(uch, G1.l_buf, INBUFSIZ);
>         ALLOC(uch, G1.outbuf, OUTBUFSIZ);
> --
> 2.3.3
>
> _______________________________________________
> busybox mailing list
> busybox@busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic