JMH microbenchmarks comparing zstd-java against the two common JVM zstd options:
| Contestant | Binding | Modes benchmarked |
|---|---|---|
| zstd-java (this project) | FFM (no JNI) | byte[] and zero-copy MemorySegment |
zstd-jni (com.github.luben) |
JNI | byte[] |
aircompressor (io.airlift:aircompressor-v3) |
pure Java | byte[] |
The MemorySegment path is the one we expect to win: input and output are
already off-heap, so there is no byte[] copy in or out of native code.
Two suites, each across payload sizes 1 KiB / 64 KiB / 1 MiB at level 3:
CompressBenchmarkDecompressBenchmark
Payloads (BenchData) are deterministic, ~3x-compressible text so the ratios
are realistic rather than all-zeros or random noise.
./mvnw -q -pl benchmark -am package -DskipTestsProduces a self-contained benchmark/target/benchmarks.jar. The host's native
libzstd JAR is pulled in automatically by the platform profile.
# everything (full warmup/measurement — takes a few minutes)
java -jar benchmark/target/benchmarks.jar
# one suite, one size
java -jar benchmark/target/benchmarks.jar CompressBenchmark -p size=1048576
# quick smoke run
java -jar benchmark/target/benchmarks.jar -f 1 -wi 1 -i 3 -p size=65536--enable-native-access=ALL-UNNAMED is applied to forked JVMs via @Fork, so
no extra flags are needed.
Throughput is ops/ms (higher is better). Compare rows at the same (size):
Benchmark (size) Mode Cnt Score Units
CompressBenchmark.zstdJavaSegment 65536 thrpt 5 ... ops/ms
CompressBenchmark.zstdJavaBytes 65536 thrpt 5 ... ops/ms
CompressBenchmark.zstdJni 65536 thrpt 5 ... ops/ms
CompressBenchmark.aircompressor 65536 thrpt 5 ... ops/ms
Microbenchmark numbers are machine-specific; rebuild and run on the target host. Heed JMH's own caveat printed after each run.