Skip to content

Instantly share code, notes, and snippets.

@themoah
Last active August 26, 2025 19:26
Show Gist options
  • Select an option

  • Save themoah/09f5eed492f5a3d86107896623b58db6 to your computer and use it in GitHub Desktop.

Select an option

Save themoah/09f5eed492f5a3d86107896623b58db6 to your computer and use it in GitHub Desktop.
plugins {
id 'application'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'com.github.luben:zstd-jni:1.5.5-6'
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.3'
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
application {
mainClass = 'com.benchmark.ZstdBenchmark'
}
tasks.named('test') {
useJUnitPlatform()
}
package com.benchmark;
import com.github.luben.zstd.ZstdCompressCtx;
import com.github.luben.zstd.ZstdDictCompress;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.zip.GZIPOutputStream;
public class ZstdBenchmark {
private static final int ITERATIONS = 10;
private static final int MIN_LEVEL = 1;
private static final int MAX_LEVEL = 10;
private static final String DATA_FILE = "measurements.txt";
private static final String DICT_FILE = "values.dict";
private byte[] data;
private byte[] dictionary;
public ZstdBenchmark() throws IOException {
loadData();
}
private void loadData() throws IOException {
System.out.println("NEW Loading raw data from " + DATA_FILE);
data = Files.readAllBytes(Paths.get(DATA_FILE));
System.out.println("Loaded " + data.length + " bytes");
try {
dictionary = Files.readAllBytes(Paths.get(DICT_FILE));
System.out.println("Loaded dictionary from " + DICT_FILE + " (" + dictionary.length + " bytes)");
} catch (IOException e) {
System.out.println("Dictionary file not found: " + DICT_FILE + " (dictionary benchmarks will be skipped)");
dictionary = null;
}
System.out.println();
}
public void runBenchmark() {
System.out.println("Zstd Compression Benchmark:");
System.out.printf("%-6s %-12s %-12s %-12s %-12s%n",
"Level", "Min (ms)", "Avg (ms)", "Max (ms)", "Size (bytes)");
System.out.println("--------------------------------------------------------");
for (int level = MIN_LEVEL; level <= MAX_LEVEL; level++) {
benchmarkLevel(level);
}
if (dictionary != null) {
System.out.println();
System.out.println("Zstd with Dictionary Compression Benchmark:");
System.out.printf("%-6s %-12s %-12s %-12s %-12s%n",
"Level", "Min (ms)", "Avg (ms)", "Max (ms)", "Size (bytes)");
System.out.println("--------------------------------------------------------");
for (int level = MIN_LEVEL; level <= MAX_LEVEL; level++) {
benchmarkDictLevel(level);
}
}
System.out.println("GZIP Compression Benchmark:");
System.out.printf("%-6s %-12s %-12s %-12s %-12s%n",
"Level", "Min (ms)", "Avg (ms)", "Max (ms)", "Size (bytes)");
System.out.println("--------------------------------------------------------");
for (int level = 1; level <= 9; level++) {
benchmarkGzipLevel(level);
}
System.out.println();
}
private void benchmarkGzipLevel(int level) {
long[] times = new long[ITERATIONS];
int compressedSize = 0;
for (int i = 0; i < ITERATIONS; i++) {
long startTime = System.nanoTime();
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
GZIPOutputStream gzipOut = new GZIPOutputStream(
new BufferedOutputStream(baos, 65536)) {
{
def.setLevel(level);
}
};
gzipOut.write(data);
gzipOut.close();
byte[] compressed = baos.toByteArray();
compressedSize = compressed.length;
} catch (IOException e) {
System.err.println("Error during GZIP compression: " + e.getMessage());
return;
}
long endTime = System.nanoTime();
times[i] = endTime - startTime;
}
Arrays.sort(times);
long minTime = times[0] / 1_000_000;
long maxTime = times[ITERATIONS - 1] / 1_000_000;
long avgTime = Arrays.stream(times).sum() / ITERATIONS / 1_000_000;
System.out.printf("%-6d %-12d %-12d %-12d %-12d%n",
level, minTime, avgTime, maxTime, compressedSize);
}
private void benchmarkDictLevel(int level) {
long[] times = new long[ITERATIONS];
int compressedSize = 0;
try (ZstdCompressCtx ctx = new ZstdCompressCtx();
ZstdDictCompress dictCompress = new ZstdDictCompress(dictionary, level)) {
ctx.loadDict(dictCompress);
ctx.setLevel(level);
ctx.setWorkers(4);
for (int i = 0; i < ITERATIONS; i++) {
long startTime = System.nanoTime();
byte[] compressed = ctx.compress(data);
long endTime = System.nanoTime();
times[i] = endTime - startTime;
compressedSize = compressed.length;
}
}
Arrays.sort(times);
long minTime = times[0] / 1_000_000;
long maxTime = times[ITERATIONS - 1] / 1_000_000;
long avgTime = Arrays.stream(times).sum() / ITERATIONS / 1_000_000;
System.out.printf("%-6d %-12d %-12d %-12d %-12d%n",
level, minTime, avgTime, maxTime, compressedSize);
}
private void benchmarkLevel(int level) {
long[] times = new long[ITERATIONS];
int compressedSize = 0;
try (ZstdCompressCtx ctx = new ZstdCompressCtx()) {
ctx.setWorkers(4);
ctx.setLevel(level);
for (int i = 0; i < ITERATIONS; i++) {
long startTime = System.nanoTime();
byte[] compressed = ctx.compress(data);
long endTime = System.nanoTime();
times[i] = endTime - startTime;
compressedSize = compressed.length;
}
}
Arrays.sort(times);
long minTime = times[0] / 1_000_000;
long maxTime = times[ITERATIONS - 1] / 1_000_000;
long avgTime = Arrays.stream(times).sum() / ITERATIONS / 1_000_000;
System.out.printf("%-6d %-12d %-12d %-12d %-12d%n",
level, minTime, avgTime, maxTime, compressedSize);
}
public static void main(String[] args) {
try {
ZstdBenchmark benchmark = new ZstdBenchmark();
benchmark.runBenchmark();
} catch (IOException e) {
System.err.println("Error loading data: " + e.getMessage());
System.exit(1);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment