Repository navigation
Use zstd compression #478
Copy link
Copy link
Closed
AppImageCommunity/libappimage
#158Description
- A zstd patch is available for squashfuse at Add zstd compression support vasi/squashfuse#23
- Zstd support has been added to SquashFS in the kernel in commit torvalds/linux@87bf54b.
- Support is ready for mksquashfs and is coming to squashfs-tools soon https://sourceforge.net/p/squashfs/mailman/message/35996905/.
Add zstd compression and decompression support to SquashFS. zstd is a
great fit for SquashFS because it can compress at ratios approaching xz,
while decompressing twice as fast as zlib. For SquashFS in particular,
it can decompress as fast as lzo and lz4. It also has the flexibility
to turn down the compression ratio for faster compression times.
The compression benchmark is run on the file tree from the SquashFS archive
found in ubuntu-16.10-desktop-amd64.iso [1]. It uses `mksquashfs` with the
default block size (128 KB) and and various compression algorithms/levels.
xz and zstd are also benchmarked with 256 KB blocks. The decompression
benchmark times how long it takes to `tar` the file tree into `/dev/null`.
See the benchmark file in the upstream zstd source repository located under
`contrib/linux-kernel/squashfs-benchmark.sh` [2] for details.
I ran the benchmarks on a Ubuntu 14.04 VM with 2 cores and 4 GiB of RAM.
The VM is running on a MacBook Pro with a 3.1 GHz Intel Core i7 processor,
16 GB of RAM, and a SSD.
| Method | Ratio | Compression MB/s | Decompression MB/s |
|----------------|-------|------------------|--------------------|
| gzip | 2.92 | 15 | 128 |
| lzo | 2.64 | 9.5 | 217 |
| lz4 | 2.12 | 94 | 218 |
| xz | 3.43 | 5.5 | 35 |
| xz 256 KB | 3.53 | 5.4 | 40 |
| zstd 1 | 2.71 | 96 | 210 |
| zstd 5 | 2.93 | 69 | 198 |
| zstd 10 | 3.01 | 41 | 225 |
| zstd 15 | 3.13 | 11.4 | 224 |
| zstd 16 256 KB | 3.24 | 8.1 | 210 |
This patch was written by Sean Purcell <[email protected]>, but I will be
taking over the submission process.
[1] http://releases.ubuntu.com/16.10/
[2] https://github.com/facebook/zstd/blob/dev/contrib/linux-kernel/squashfs-benchmark.sh
zstd source repository: https://github.com/facebook/zstd
Signed-off-by: Sean Purcell <[email protected]>
Signed-off-by: Nick Terrell <[email protected]>
Signed-off-by: Chris Mason <[email protected]>
Acked-by: Phillip Lougher <[email protected]>
Reactions are currently unavailable
Activity
develar commentedon Oct 7, 2017
It would be amazing, because electron-builder uses lzma for windows nsis targets — expected size 35 MB. AppImage uses deflate and size ~51 MB (even more — because 7za is not used, compression is not good (e.g. 7za can compress the same data to 50 MB (1.5 MB difference))).
Yes, we use lzma2 for windows portable and users don't complain that start time is slow, but anyway, for now I decided to not use xz for AppImage because of decompression speed.
Calinou commentedon Oct 8, 2017
Will AppImages using zstd work on older kernels, such as the ones found in Ubuntu LTS, CentOS or Debian?
probonopd commentedon Oct 9, 2017
If we would implement zstd, then we would implement it in FUSE, which means it would be independent of the kernel. But we would lose the ability to loop-mount such AppImages using old kernels (is anyone ever doing that, anyway?)
probonopd commentedon Oct 9, 2017
@develar if it is not too much trouble, could you give the following numbers please?
TheAssassin commentedon Oct 9, 2017
We wouldn't lose it, but it won't work on old systems, right? I assume that on newer systems, it should work out of the box, but on older ones, it'd produce an error message.
probonopd commentedon Oct 9, 2017
Correct. Sorry, I meant "old kernels". Corrected above.
probonopd commentedon Nov 14, 2017
Zstandard support has been added to squashfs-tools, so if I am not mistaken nothing is stopping us now from using Zstandard for AppImages.
Volunteers for a PR?
probonopd commentedon Dec 4, 2017
zstd library
squashfs-tools
squashfuse
probonopd commentedon Dec 9, 2017
https://github.com/vasi/squashfuse/releases/tag/0.1.101 now contains zstd support.
TheAssassin commentedon Dec 9, 2017
We should update it in a PR branch, and check whether it builds with that new version.
ambyjkl commentedon Apr 25, 2020
Any updates on this issue? I think by this point, zstd support is pretty universal
probonopd commentedon Apr 25, 2020
Hi @ambyjkl looks like no one has done any work on this. First step would be to scientifically prove that it actually provides some advantage over what we have in place now.
35 remaining items
brunoais commentedon Feb 14, 2024
The main issue this has is its
0.1sleep which means that the numbers you show are only reliable to a between -0.2 to 0 seconds. The 2nd decimal digit has no reliable value and the first decimal digit is so-so.As long as you stay in the realm of the
0.5s, it's okmralusw commentedon Apr 5, 2024
@Samueru-sama @probonopd the
mksquashfsdefault iszstd:15. Nothing to do withappimagetool.Luckily it's simple enough to change the level, by passing
appimagetoolthe--mksquashfs-optflag twice (becausemksquashfsdoesn't take-Xcompression-level=N— it insists on two separate CLI args; hey, what did you expect from a tool that seems bent on having inconvenient usage?):mralusw commentedon Apr 5, 2024
@probonopd if you want to implement different compression levels, I'd suggest accepting "zstd:N" (just as
mount.btrfsaccepts). There are tools that callappimagetoolinternally (linuxdeploy), and an extra level of CLI arg wrapping gets a bit insane.probonopd commentedon Apr 5, 2024
Well, ideally we find the optimal ("balanced") settings and set them for everyone. So that we make the choice, and not every application developer has to think about which compression level to use.
mralusw commentedon Apr 5, 2024
So in essence you're suggesting making it worse than it already is (because right now I can set all the knobs, including block size, to what I know is good for my specific use case). It is a trend I find in a lot of software nowadays, let's not name names.
Have your mythical "balanced" setting, but don't make me break open and re-create the appimage if your compression level, squashfs block size etc don't suit me.
mralusw commentedon Apr 5, 2024
Frankly I doubt there is an optimal level. It depends on the contents, but also on the purpose and nature of the appimage. The app can start fast or slow independently from the unpacked size (maybe it takes ten seconds to scan the system or connect to a server before it's even usable). The developer might favor a small size for easy downloads, or little compression for a fast startup, and you wouldn't know. Etcetera.
Researching the "balanced" setting would be a full time job of surveying your "customers" (appimage developers), and still half of them, by definition won't be pleased with the default. It's your call, but maybe there are more useful things to implement (if anything new gets implemented at this point).
Samueru-sama commentedon Apr 5, 2024
If you ask me the optimal level is zstd:1, it gives similar comp ratios to gzip while being much faster at decompression.
Something similar also happens with zstd is used on Btrfs for filesystem level compression, it is only zstd:1 that makes sense, and sometimes zstd:2 is better under some workloads but the difference is less than 2%.
mgord9518 commentedon Apr 5, 2024
@Samueru-sama If you're going to go that low, you might as well use lz4_hc, which also has compression similar to gzip but is about twice as fast as zstd and has a much smaller space overhead in the runtime.
zstd shines at mid-high compression levels, so "optimal" is probably in the range of 12-17 (15 is the default level for mksquashfs). So you'd get better compression than gzip and still get substantially faster decompression
Developers should definitely be able to choose something else if it provides a better experience for their application though
Samueru-sama commentedon Apr 6, 2024
How can I benchmark lz4_hc? I only found a github issue where the user was told to use lz4:9 instead.
Either way I just did a quick test using the librewolf AppDIr as a compressed tar file:
And the sizes of the files were 86.5MiB for zstd:15, 87.7MiB for zstd:12, 116.7MiB for zstd:1 and 124.8MiB for lz4:9.
Which yeah these benchmarks give the idea that zstd:12-15 is good, but as seen in the tests above when actually opening the appimage the default zstd compression of mksquashfs was adding a considerable delay, even slower than gzip.
mralusw commentedon Apr 6, 2024
If you measure sub-second timings (which have a considerable variance as I can see from the various timings you quoted) use sharkdp/hyperfine. E.g.
hyperfine -r 10 'cmd1 ...' 'cmd2 ...'. Otherwise you're measuring noise.mgord9518 commentedon Apr 6, 2024
@Samueru-sama What I do is make SquashFS images of various levels, then test reading and other simple file operations. FUSE also caches files, so you get a significant speed-up after the first read. I've never had any issues with lz4_hc, what was the issue you saw about?
As for the AppImages, I'm not sure why higher zstd ratios would be so much slower, that shouldn't be the case because using squashfuse I didn't seem to notice any massive slow-downs, certainly not any that would make it slower than gzip.
When benchmarking SquashFS compression, tar files should be avoided, they give a good indication as to how fast the decompression itself is as a whole, but speed and file size might be different when compressed into blocks, like in SquashFS. Use mksquashfs then mount with squashfuse and test that instead
Samueru-sama commentedon Apr 6, 2024
I haven't had issues with lz4_hc (because I've never used it lol), just that I asked you how to benchmark it because when I searched for it the info I got is that I should use lz4:9 instead. I asked you because you said that instead of zstd:1 one should use lz4_hc.
I just repeated my tests of zstd (defaults which seems to be zstd 15) vs gzip (and modified the script a little bit) with the librewolf appimage:
(Once again I just did here was --appimage-extract the librewolf appimage and made a new zstd appimage using appimagetool using its defaults, the title of the appimage indicates the type in the results)
And just for the heck of it, I decided to make again the zstd1 level one appimage using the method that @mralusw suggested:
appimagetool --comp zstd --mksquashfs-opt -Xcompression-level --mksquashfs-opt 3 ./LibreWolf.AppDirAnd it did make a zstd:1 appimages I think, because this appimage is 117.6 MiB, however when I tested it wasn't faster than the original appimage (gzip), which is odd because in the older tests zstd1 was significantly faster than the others:
So I went and made the appimage again manually using
mksquashfs ./LibreWolf.AppDir Manual-zstd-1 -comp zstd -Xcompression-level 1andcat Manual-zstd-1 >> runtime-x86_64This zstd:1 appimage is 122.5 MiB (No idea why there's a size difference) however it does start up quite fast like it should:
So hmmm yeah, there's something other than the zstd compression level at play here. This is the updated script I'm using, for it to work you would need to do this test using i3wm:
And if you want the appimages I made for these tests, just let know and I'll give you link.
Edit: Also if you wonder, here is the startup time of a native librewolf (no appimage):
mralusw commentedon Apr 6, 2024
@Samueru-sama
That makes a zstd:3, not a zstd:1. Look at the args. Every appimagetool
--mksquashfsarg passes the next arg tomksquashfsSamueru-sama commentedon Apr 6, 2024
Oh my bad, I did actually change the
--mksquashfs-opt 3to 1 in my tests, just that I pasted it here I forgot to change the number. Just checked my zsh history and it does have the1in there.And just to be extra sure I did make it again this time making sure that it is
--mksquashfs-opt 1and the resulting size is 117.6 MiB like I said before, changing it to 3 makes it 104.8 MiB instead.probonopd commentedon Oct 6, 2026
Apparently zstandard already has a successor: OpenZL. It needs to be checked out.