1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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;
|