Show HN: misa77 - 一种解码速度比 LZ4 快两倍(且压缩比更好)的编解码器
Show HN: misa77 - a codec that decodes 2x faster than LZ4 (at better ratios)

原始链接: https://github.com/welcome-to-the-sunny-side/misa77

**misa77** 是一款基于 LZ 的编解码器,专为“一次写入,多次读取”的应用场景设计,在压缩速度与极高的单线程解压吞吐量之间,优先保证后者。 **主要特性:** * **性能:** 在解压吞吐量与压缩比的权衡上,它处于帕累托最优边界。在解压速度方面,它始终优于常见的快速编解码器(如 LZ4、Snappy 和 Zstd),特别是在处理高压缩率数据时。 * **资源效率:** 无论输入数据大小如何,它都能保持恒定的内存占用——压缩时低于 5 MB,解压时为 0 MB。 * **灵活性:** 提供多种压缩级别和实验性模式(如 `--yolo` 或 `--adaptive`),允许用户以牺牲压缩时间为代价,针对特定 CPU 微架构优化解压吞吐量。 * **局限性:** 压缩速度较慢是刻意设计的。该项目目前处于 v0.x.y 阶段,意味着文件格式可能会发生变化,应将其视为实验性软件,而非已完全加固的生产工具。 **使用说明:** misa77 是一款无依赖的 C++20 命令行工具,适用于 64 位小端序系统。它需要 POSIX 环境,并通过 CMake 标志支持原生硬件优化。

一款全新的数据压缩编解码器 **misa77** 已经发布,其解压速度显著快于 LZ4,并实现了具有竞争力的压缩比。 主要特性包括: * **高性能:** 解压吞吐量高达 5,219 MB/s,有效实现了标准 LZ4 两倍的速度。 * **优化:** 该格式专为现代乱序执行 CPU 架构设计,通过最小化分支预测来提升效率。 * **权衡:** 虽然其解压性能处于同类压缩算法的顶尖水平,但与 LZ4 相比,该编解码器的压缩速度显著较慢。 在 Silesia 基准测试集上的结果证实,misa77 在原始速度和压缩比两方面均优于 LZ4,使其成为读取密集型或性能关键型环境的理想替代方案。
相关文章

原文

misa77 is an LZ-based codec that targets the write-once, read-many niche. In particular, it aims to satisfy the following criteria:

  • Extremely high decompression throughput (single-threaded).
  • Modest compression ratios (it has no entropy backend, so one can obviously not compare it to something like zstd, but LZ4 at high effort levels is a good reference point).
  • Constant memory use, regardless of input size (<= 5 MB across all compression modes, and 0 MB for decompression).

Slow compression is the obvious tradeoff that one makes to achieve the above.

In addition, misa77 has a somewhat synergizing tendency to decompress highly compressed files faster, leading to the following results:

  • It offers particularly high decompression throughput on highly compressible files.
  • Even for moderately compressible files, spending more effort during compression to get a more compressed result leads to better decompression throughput (alongside the natural advantage of better ratios).

This makes high-effort compression particularly attractive for misa77, and inspires some experimental compression modes (refer to src/experimental/) that aim to spend more effort at compression time to produce a compressed stream that is friendlier to the microarchitectures of most CPUs when decompressing said streams.

misa77 also has two compression effort levels as of v0.2.0:

  • level 0: offers better decode throughput, slightly worse ratio, similar encode throughput
  • level 1 (default): offers slightly worse decode throughput, better ratio, similar encode throughput

The underlying stream format (used by the library functions) and the container format for .misa77 files (produced by the CLI) can be found in docs/.

Detailed results are listed ahead, but here's a terse summary:

  • misa77 lies on the pareto frontier for decompression throughput vs compression ratio on most shapes of data.
  • It very frequently decompresses faster even when competitors have a significantly worse ratio.
  • It is quite slow at compression.

Cross-Platform results for v0.1.0 (across Intel x86-64, AMD x86-64, ARM64) can be found here. Note that these are likely outdated at the time of you reading this.

Some detailed results for Intel x86-64 follow.

Setup:

  • CPU: Intel(R) Core(TM) i7-14650HX (@2.2 GHz) (Intel Turbo disabled).
  • Single threaded, pinned to a single performance core.
  • CPU governor set to performance.
  • The benchmarking harness is a public fork of lzbench, and can be accessed here.

misa77 rows first, then competitors are sorted by decompression speed.

Compressor name Compression Decompress. Ratio Filename
misa77 0.2.0 -0 54.5 MB/s 5219 MB/s 42.64 silesia.tar
misa77 0.2.0 -1 51.2 MB/s 4274 MB/s 39.65 silesia.tar
zxc 0.12.0 -3 115 MB/s 2841 MB/s 45.46 silesia.tar
zxc 0.12.0 -4 80.8 MB/s 2726 MB/s 42.63 silesia.tar
lzsse8fast 2019-04-18 183 MB/s 2661 MB/s 44.80 silesia.tar
zxc 0.12.0 -5 48.6 MB/s 2599 MB/s 40.25 silesia.tar
lz4hc 1.10.0 -12 7.31 MB/s 2531 MB/s 36.45 silesia.tar
lzsse4fast 2019-04-18 186 MB/s 2522 MB/s 45.26 silesia.tar
lz4 1.10.0 371 MB/s 2505 MB/s 47.59 silesia.tar
lizard 2.1 -10 320 MB/s 2452 MB/s 48.79 silesia.tar
zstd 1.5.7 -1 297 MB/s 901 MB/s 34.54 silesia.tar
snappy 1.2.2 375 MB/s 855 MB/s 47.89 silesia.tar

Compressor name Compression Decompress. Ratio Filename
misa77 0.2.0 -0 38.7 MB/s 4802 MB/s 48.59 enwik8
misa77 0.2.0 -1 40.6 MB/s 4134 MB/s 44.05 enwik8
zxc 0.12.0 -3 70.1 MB/s 2674 MB/s 52.05 enwik8
zxc 0.12.0 -5 38.7 MB/s 2627 MB/s 46.85 enwik8
zxc 0.12.0 -4 52.7 MB/s 2593 MB/s 48.60 enwik8
lzsse4fast 2019-04-18 141 MB/s 2581 MB/s 47.11 enwik8
lzsse8fast 2019-04-18 135 MB/s 2553 MB/s 47.25 enwik8
lizard 2.1 -10 240 MB/s 2462 MB/s 57.31 enwik8
lz4 1.10.0 276 MB/s 2355 MB/s 57.26 enwik8
lz4hc 1.10.0 -12 9.89 MB/s 2167 MB/s 41.91 enwik8
zstd 1.5.7 -1 225 MB/s 831 MB/s 40.66 enwik8
snappy 1.2.2 240 MB/s 568 MB/s 55.93 enwik8

As misa77's performance is quite "spiky" (depending on the shape of the data being compressed), a file-level breakdown for the silesia corpus yields some interesting insights into its performance.

Note:

Decode speed relative to lz4

At level 0, misa77 decodes faster than lz4 on all 12 files (some by huge margins). All other levels decode faster on 11/12 files. The exception is x-ray, which is highly incompressible (lz4 has a ratio of nearly 1.0 on this file and essentially devolves to a memcpy).

misa77 per-file decode speed vs lz4, all four modes, Silesia (Intel)

Throughput vs ratio, against popular fast-decode codecs

On the compressible files, misa77 sits on the decode-throughput/ratio Pareto frontier: it decodes fastest while ~matching or beating the ratio of the other fast-LZ codecs. sao and x-ray are exceptions due to the reasons stated before.

misa77 vs other codecs: per-file decode throughput vs ratio, Silesia (Intel)

  • A C++20 compiler (both GCC and Clang are fine).
  • CMake >= 3.20.
  • A little-endian 64-bit system.
  • The misa CLI needs POSIX (Linux, macOS).

Note: On x86-64, AVX2/SSE2 are selected at runtime. Other architectures use a portable path that has no explicit intrinsics, but is easily auto-vectorizable by compilers (and from my testing, does auto-vectorize on Apple ARM at the very least).

cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build

This produces the misa CLI at build/misa. For a binary tuned to the exact machine you'll run it on, add -DMISA77_MARCH=native (I recommend this). To run the round-trip test:

misa is a single, dependency-free binary with three file-based subcommands. It operates on single files only (there's no directory or pipe support, so tar first if you need those).

misa compress   FILE          # -> FILE.misa77
misa decompress FILE.misa77   # -> FILE
misa suggest    FILE          # -> FILE.misap  (tuned params)

misa compress takes -l N / --level N to pick the compression level (default is 1).

There are also some experimental compression modes (at most one at a time, not combinable with --level):

Flag Effect
--adaptive autotune the compressor based on the input for decode speed (only use this with homogeneous data)
--params F.misap compress with a vector from misa suggest
--yolo high-effort, decode-optimized

--adaptive and suggest also take --tune loose / --tune tight (similar tradeoffs as level 0/1, and the default is loose) and --sample MB (how much input to sample when picking params, default is 2 MB). Everywhere, -o PATH sets the output path and -f overwrites without asking.

misa compress -l 0 enwik8                # enwik8 -> enwik8.misa77, fastest-decode level
misa decompress enwik8.misa77            # back to enwik8

# tune on a sample, then reuse the params:
misa suggest --tune tight data.bin       # -> data.misap
misa compress --params data.misap data.bin
  1. misa77's format may change unexpectedly as it's still v0.x.y.
  2. The decoder assumes that the input is a valid misa77 stream. Invalid input is UB and I offer no guarantees for whatever misa77 does in this case.
  3. It's been through some local fuzzing but is not hardened, so treat it as experimental.

Note: misa77 has evolved out of a less polished endeavour to learn performance engineering, and its history can be found in this archived repository.

Inspiration has been taken from:

Lastly, Claude Opus 4.8 and Fable 5 helped a lot with scripting, tooling, and building the CLI.

MIT (see LICENSE).

联系我们 contact @ memedata.com