summaryrefslogtreecommitdiff
path: root/neozip/test/benchmarks/benchmark_deflate.cc
diff options
context:
space:
mode:
Diffstat (limited to 'neozip/test/benchmarks/benchmark_deflate.cc')
-rw-r--r--neozip/test/benchmarks/benchmark_deflate.cc147
1 files changed, 147 insertions, 0 deletions
diff --git a/neozip/test/benchmarks/benchmark_deflate.cc b/neozip/test/benchmarks/benchmark_deflate.cc
new file mode 100644
index 0000000000..f60e2589d1
--- /dev/null
+++ b/neozip/test/benchmarks/benchmark_deflate.cc
@@ -0,0 +1,147 @@
+/* benchmark_deflate.cc -- benchmark deflate() with various levels and raw mode
+ * Copyright (C) 2026 Nathan Moinvaziri
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <benchmark/benchmark.h>
+
+extern "C" {
+# include "zbuild.h"
+# include "zutil_p.h"
+# if defined(ZLIB_COMPAT)
+# include "zlib.h"
+# else
+# include "zlib-ng.h"
+# endif
+# include "test/compressible_data_p.h"
+}
+
+#define MAX_SIZE (1024 * 1024)
+
+/* Parameterized deflate benchmark: Args(size, level) */
+class deflate_bench: public benchmark::Fixture {
+private:
+ uint8_t *inbuff = nullptr;
+ uint8_t *outbuff = nullptr;
+ z_uintmax_t outbuff_size = 0;
+
+public:
+ void SetUp(::benchmark::State& state) {
+ outbuff_size = PREFIX(deflateBound)(NULL, MAX_SIZE);
+ outbuff = (uint8_t *)malloc(outbuff_size);
+ if (outbuff == NULL) {
+ state.SkipWithError("malloc failed");
+ return;
+ }
+
+ inbuff = gen_compressible_data(MAX_SIZE);
+ if (inbuff == NULL) {
+ free(outbuff);
+ outbuff = NULL;
+ state.SkipWithError("gen_compressible_data() failed");
+ return;
+ }
+ }
+
+ void Bench(benchmark::State& state, int window_bits, int strategy = Z_DEFAULT_STRATEGY) {
+ int err;
+ size_t size = (size_t)state.range(0);
+ int level = (int)state.range(1);
+
+ PREFIX3(stream) strm;
+ strm.zalloc = NULL;
+ strm.zfree = NULL;
+ strm.opaque = NULL;
+ strm.total_in = 0;
+ strm.total_out = 0;
+ strm.next_out = NULL;
+ strm.avail_out = 0;
+
+ err = PREFIX(deflateInit2)(&strm, level, Z_DEFLATED, window_bits, MAX_MEM_LEVEL, strategy);
+ if (err != Z_OK) {
+ state.SkipWithError("deflateInit2 did not return Z_OK");
+ return;
+ }
+
+ for (auto _ : state) {
+ err = PREFIX(deflateReset)(&strm);
+ if (err != Z_OK) {
+ state.SkipWithError("deflateReset did not return Z_OK");
+ PREFIX(deflateEnd)(&strm);
+ return;
+ }
+
+ strm.avail_in = (uint32_t)size;
+ strm.next_in = (z_const uint8_t *)inbuff;
+ strm.next_out = outbuff;
+ strm.avail_out = (uint32_t)outbuff_size;
+
+ err = PREFIX(deflate)(&strm, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ state.SkipWithError("deflate did not return Z_STREAM_END");
+ PREFIX(deflateEnd)(&strm);
+ return;
+ }
+ }
+
+ err = PREFIX(deflateEnd)(&strm);
+ if (err != Z_OK) {
+ state.SkipWithError("deflateEnd did not return Z_OK");
+ return;
+ }
+ }
+
+ void TearDown(const ::benchmark::State&) {
+ free(inbuff);
+ free(outbuff);
+ }
+};
+
+#define BENCHMARK_DEFLATE_ARGS \
+ ->Args({1024, 1})->Args({1024, 3})->Args({1024, 6})->Args({1024, 9}) \
+ ->Args({16384, 1})->Args({16384, 3})->Args({16384, 6})->Args({16384, 9}) \
+ ->Args({131072, 1})->Args({131072, 3})->Args({131072, 6})->Args({131072, 9}) \
+ ->Args({1048576, 1})->Args({1048576, 3})->Args({1048576, 6})->Args({1048576, 9})
+
+/* Parameterized deflate with zlib wrapping (includes adler32 checksum) */
+BENCHMARK_DEFINE_F(deflate_bench, deflate_level)(benchmark::State& state) {
+ Bench(state, MAX_WBITS);
+}
+BENCHMARK_REGISTER_F(deflate_bench, deflate_level) BENCHMARK_DEFLATE_ARGS;
+
+/* Parameterized raw deflate without checksum */
+BENCHMARK_DEFINE_F(deflate_bench, deflate_nocrc)(benchmark::State& state) {
+ Bench(state, -MAX_WBITS);
+}
+BENCHMARK_REGISTER_F(deflate_bench, deflate_nocrc) BENCHMARK_DEFLATE_ARGS;
+
+/* Strategy benchmarks use fewer size/level combos to keep test count reasonable */
+#define BENCHMARK_DEFLATE_STRATEGY_ARGS \
+ ->Args({1024, 1})->Args({1024, 6})->Args({1024, 9}) \
+ ->Args({1048576, 1})->Args({1048576, 6})->Args({1048576, 9})
+
+/* Parameterized deflate with filtered strategy */
+BENCHMARK_DEFINE_F(deflate_bench, deflate_filtered)(benchmark::State& state) {
+ Bench(state, MAX_WBITS, Z_FILTERED);
+}
+BENCHMARK_REGISTER_F(deflate_bench, deflate_filtered) BENCHMARK_DEFLATE_STRATEGY_ARGS;
+
+/* Parameterized deflate with Huffman-only strategy */
+BENCHMARK_DEFINE_F(deflate_bench, deflate_huffman)(benchmark::State& state) {
+ Bench(state, MAX_WBITS, Z_HUFFMAN_ONLY);
+}
+BENCHMARK_REGISTER_F(deflate_bench, deflate_huffman) BENCHMARK_DEFLATE_STRATEGY_ARGS;
+
+/* Parameterized deflate with RLE strategy */
+BENCHMARK_DEFINE_F(deflate_bench, deflate_rle)(benchmark::State& state) {
+ Bench(state, MAX_WBITS, Z_RLE);
+}
+BENCHMARK_REGISTER_F(deflate_bench, deflate_rle) BENCHMARK_DEFLATE_STRATEGY_ARGS;
+
+/* Parameterized deflate with fixed Huffman codes */
+BENCHMARK_DEFINE_F(deflate_bench, deflate_fixed)(benchmark::State& state) {
+ Bench(state, MAX_WBITS, Z_FIXED);
+}
+BENCHMARK_REGISTER_F(deflate_bench, deflate_fixed) BENCHMARK_DEFLATE_STRATEGY_ARGS;