diff options
Diffstat (limited to 'neozip/test/benchmarks/benchmark_deflate.cc')
| -rw-r--r-- | neozip/test/benchmarks/benchmark_deflate.cc | 147 |
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; |
