Skip to content

Commit bbcdf11

Browse files
committed
feat(example): add memory benchmark example
1 parent 66e0d18 commit bbcdf11

File tree

3 files changed

+191
-0
lines changed

3 files changed

+191
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../google_benchmark_cmake/memory_bench.hpp

examples/google_benchmark_cmake/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "fibonacci_bench.hpp"
66
#include "fixture_bench.hpp"
7+
#include "memory_bench.hpp"
78
#include "multithread_bench.hpp"
89
#include "pause_timing_bench.hpp"
910
#include "sleep_bench.hpp"
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
#pragma once
2+
3+
#include <benchmark/benchmark.h>
4+
5+
#include <string>
6+
#include <vector>
7+
8+
// Run-length encoding: compress consecutive repeated characters
9+
// Example: "aaabbbccc" -> "3a3b3c"
10+
static std::string rle_encode(const std::string& input) {
11+
if (input.empty()) return "";
12+
13+
std::string result;
14+
result.reserve(input.size()); // Pre-allocate reasonable size
15+
16+
char current = input[0];
17+
size_t count = 1;
18+
19+
for (size_t i = 1; i < input.size(); ++i) {
20+
if (input[i] == current) {
21+
count++;
22+
} else {
23+
result += std::to_string(count) + current;
24+
current = input[i];
25+
count = 1;
26+
}
27+
}
28+
result += std::to_string(count) + current;
29+
30+
return result;
31+
}
32+
33+
// Run-length decoding: decompress RLE encoded string
34+
// Example: "3a3b3c" -> "aaabbbccc"
35+
static std::string rle_decode(const std::string& input) {
36+
std::string result;
37+
size_t i = 0;
38+
39+
while (i < input.size()) {
40+
// Parse the count
41+
size_t count = 0;
42+
while (i < input.size() && std::isdigit(input[i])) {
43+
count = count * 10 + (input[i] - '0');
44+
i++;
45+
}
46+
47+
// Get the character
48+
if (i < input.size()) {
49+
char ch = input[i];
50+
result.append(count, ch);
51+
i++;
52+
}
53+
}
54+
55+
return result;
56+
}
57+
58+
// Generate a string with patterns for RLE
59+
static std::string generate_rle_input(size_t size, size_t run_length) {
60+
std::string result;
61+
result.reserve(size);
62+
63+
const std::string chars = "abcdefghijklmnopqrstuvwxyz";
64+
size_t char_idx = 0;
65+
66+
while (result.size() < size) {
67+
size_t count = std::min(run_length, size - result.size());
68+
result.append(count, chars[char_idx % chars.size()]);
69+
char_idx++;
70+
}
71+
72+
return result;
73+
}
74+
75+
// Benchmark: RLE encoding with small runs (high compression)
76+
static void BM_RLE_Encode_SmallRuns(benchmark::State& state) {
77+
const size_t input_size = state.range(0);
78+
std::string input = generate_rle_input(input_size, 3);
79+
80+
for (auto _ : state) {
81+
std::string encoded = rle_encode(input);
82+
benchmark::DoNotOptimize(encoded);
83+
benchmark::ClobberMemory();
84+
}
85+
86+
state.SetBytesProcessed(state.iterations() * input_size);
87+
}
88+
BENCHMARK(BM_RLE_Encode_SmallRuns)
89+
->Arg(100)
90+
->Arg(1000)
91+
->Arg(10000)
92+
->Arg(100000);
93+
94+
// Benchmark: RLE encoding with large runs (low compression)
95+
static void BM_RLE_Encode_LargeRuns(benchmark::State& state) {
96+
const size_t input_size = state.range(0);
97+
std::string input = generate_rle_input(input_size, 100);
98+
99+
for (auto _ : state) {
100+
std::string encoded = rle_encode(input);
101+
benchmark::DoNotOptimize(encoded);
102+
benchmark::ClobberMemory();
103+
}
104+
105+
state.SetBytesProcessed(state.iterations() * input_size);
106+
}
107+
BENCHMARK(BM_RLE_Encode_LargeRuns)
108+
->Arg(100)
109+
->Arg(1000)
110+
->Arg(10000)
111+
->Arg(100000);
112+
113+
// Benchmark: RLE decoding
114+
static void BM_RLE_Decode(benchmark::State& state) {
115+
const size_t input_size = state.range(0);
116+
std::string input = generate_rle_input(input_size, 10);
117+
std::string encoded = rle_encode(input);
118+
119+
for (auto _ : state) {
120+
std::string decoded = rle_decode(encoded);
121+
benchmark::DoNotOptimize(decoded);
122+
benchmark::ClobberMemory();
123+
}
124+
125+
state.SetBytesProcessed(state.iterations() * encoded.size());
126+
}
127+
BENCHMARK(BM_RLE_Decode)->Arg(100)->Arg(1000)->Arg(10000)->Arg(100000);
128+
129+
// Benchmark: Vector allocations (resizing pattern)
130+
static void BM_Vector_PushBack(benchmark::State& state) {
131+
const size_t count = state.range(0);
132+
133+
for (auto _ : state) {
134+
std::vector<int> vec;
135+
for (size_t i = 0; i < count; ++i) {
136+
vec.push_back(i);
137+
}
138+
benchmark::DoNotOptimize(vec);
139+
benchmark::ClobberMemory();
140+
}
141+
}
142+
BENCHMARK(BM_Vector_PushBack)->Arg(10)->Arg(100)->Arg(1000)->Arg(10000);
143+
144+
// Benchmark: Vector allocations with reserve (optimized)
145+
static void BM_Vector_Reserve(benchmark::State& state) {
146+
const size_t count = state.range(0);
147+
148+
for (auto _ : state) {
149+
std::vector<int> vec;
150+
vec.reserve(count);
151+
for (size_t i = 0; i < count; ++i) {
152+
vec.push_back(i);
153+
}
154+
benchmark::DoNotOptimize(vec);
155+
benchmark::ClobberMemory();
156+
}
157+
}
158+
BENCHMARK(BM_Vector_Reserve)->Arg(10)->Arg(100)->Arg(1000)->Arg(10000);
159+
160+
// Benchmark: String concatenation (many allocations)
161+
static void BM_String_Concatenation(benchmark::State& state) {
162+
const size_t count = state.range(0);
163+
164+
for (auto _ : state) {
165+
std::string result;
166+
for (size_t i = 0; i < count; ++i) {
167+
result += "x";
168+
}
169+
benchmark::DoNotOptimize(result);
170+
benchmark::ClobberMemory();
171+
}
172+
}
173+
BENCHMARK(BM_String_Concatenation)->Arg(10)->Arg(100)->Arg(1000)->Arg(10000);
174+
175+
// Benchmark: String concatenation with reserve (optimized)
176+
static void BM_String_Reserve(benchmark::State& state) {
177+
const size_t count = state.range(0);
178+
179+
for (auto _ : state) {
180+
std::string result;
181+
result.reserve(count);
182+
for (size_t i = 0; i < count; ++i) {
183+
result += "x";
184+
}
185+
benchmark::DoNotOptimize(result);
186+
benchmark::ClobberMemory();
187+
}
188+
}
189+
BENCHMARK(BM_String_Reserve)->Arg(10)->Arg(100)->Arg(1000)->Arg(10000);

0 commit comments

Comments
 (0)