What does combining compression methods in 7z actually do?

Solution 1:

Generally, compressed data cannot be compressed (further) efficiently. After the first compression method has been applied, the file size cannot be decreased significantly.

The -mN=X is mainly for specifying filters (taken from Windows help file):

Supported filters:

Delta Delta filter (“It's possible to set delta offset in bytes. For example, to compress 16-bit stereo WAV files, you can set "0=Delta:4". Default delta offset is 1.”)

BCJ converter for x86 executables

BCJ2 converter for x86 executables (version 2) (“BCJ2 is a Branch converter for 32-bit x86 executables (version 2). It converts some branch instructions for increasing further compression.”)

ARM converter for ARM (little endian) executables

ARMT converter for ARM Thumb (little endian) executables

IA64 converter for IA-64 executables

PPC converter for PowerPC (big endian) executables

SPARC converter for SPARC executables

Also from the help file, an advanced example leveraging multiple output streams of the BCJ2 filter:

7z a -t7z archive.7z *.exe *.dll -m0=BCJ2 -m1=LZMA:d23 -m2=LZMA:d19 -m3=LZMA:d19      -mb0:1 -mb0s1:2 -mb0s2:3

adds *.exe and *.dll files to archive archive.7z using BCJ2 converter, LZMA with 8 MB dictionary for main output stream (s0), and LZMA with 512 KB dictionary for s1 and s2 output streams of BCJ2.

Solution 2:

It seems you can apply filters in a sequence.

This post from last year has a nice explanation:

What does the number after 7-zip's -m switch mean?

That number lets you set the order of the compression operations if you are using more than one at once.

This is an example from the documentation:

7z a a.7z *.exe *.dll -m0=BCJ2 -m1=LZMA:d25 -m2=LZMA:d19 -m3=LZMA:d19 -mb0:1 -mb0s1:2 -mb0s2:3

adds *.exe and *.dll files to archive a.7z using BCJ2 filter, LZMA with 32 MB dictionary for main output stream (s0), and LZMA with 512 KB dictionary for s1 and s2 output streams of BCJ2.

The first compression is the lowest number, which is zero. In this example, zero is set to BCJ2. Then comes one, which is LZMA. Two and three are also LZMA, but they are using different d parameters.

The -mb option is used to "bind" the output from one compression to the input of another one. In this example, BCJ2 has one input and four outputs. Output zero is going to compression number one. Output one is going to compression number two. Output two goes to compression number three. Output three is not bound (because it does not need to be compressed again).