Skip to content

Commit 1534732

Browse files
committed
Add micro-benchmark for count_min_sketch
1 parent 4014233 commit 1534732

3 files changed

Lines changed: 206 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ if (BUILD_TESTS)
7474
enable_testing()
7575
endif()
7676

77+
option(BUILD_BENCHMARKS "Build benchmarks" OFF)
78+
7779
option(COVERAGE "Enable code coverage reporting (g++/clang only)" OFF)
7880
if(COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
7981
set(CMAKE_BUILD_TYPE "Debug" FORCE)
@@ -121,6 +123,10 @@ add_subdirectory(density)
121123
add_subdirectory(tdigest)
122124
add_subdirectory(filters)
123125

126+
if (BUILD_BENCHMARKS)
127+
add_subdirectory(benchmarks)
128+
endif()
129+
124130
if (WITH_PYTHON)
125131
add_subdirectory(python)
126132
endif()

benchmarks/CMakeLists.txt

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
if (NOT TARGET benchmark::benchmark_main)
19+
include(FetchContent)
20+
21+
set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "Disable google-benchmark tests" FORCE)
22+
set(BENCHMARK_ENABLE_GTEST_TESTS OFF CACHE BOOL "Disable google-benchmark gtest tests" FORCE)
23+
set(BENCHMARK_ENABLE_INSTALL OFF CACHE BOOL "Disable google-benchmark install rules" FORCE)
24+
set(BENCHMARK_INSTALL_DOCS OFF CACHE BOOL "Disable google-benchmark documentation install" FORCE)
25+
set(BENCHMARK_ENABLE_WERROR OFF CACHE BOOL "Disable google-benchmark warnings as errors" FORCE)
26+
27+
FetchContent_Declare(
28+
googlebenchmark
29+
GIT_REPOSITORY https://github.com/google/benchmark.git
30+
GIT_TAG v1.7.1
31+
)
32+
33+
FetchContent_MakeAvailable(googlebenchmark)
34+
endif()
35+
36+
add_executable(count_min_sketch_benchmark)
37+
38+
target_link_libraries(count_min_sketch_benchmark
39+
PRIVATE
40+
count
41+
benchmark::benchmark_main
42+
)
43+
44+
set_target_properties(count_min_sketch_benchmark PROPERTIES
45+
CXX_STANDARD_REQUIRED YES
46+
)
47+
48+
target_sources(count_min_sketch_benchmark
49+
PRIVATE
50+
benchmark_count_min_sketch.cpp
51+
)
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#include <benchmark/benchmark.h>
21+
#include <count_min.hpp>
22+
23+
#include <cstddef>
24+
#include <cstdint>
25+
#include <string>
26+
#include <vector>
27+
28+
namespace
29+
{
30+
31+
using Sketch = datasketches::count_min_sketch<uint64_t>;
32+
33+
constexpr uint8_t NUM_HASHES = 7;
34+
constexpr uint32_t NUM_BUCKETS = 2718;
35+
36+
std::vector<uint64_t> makeUInt64Keys(size_t size)
37+
{
38+
std::vector<uint64_t> keys;
39+
keys.reserve(size);
40+
for (size_t i = 0; i < size; ++i)
41+
keys.push_back(static_cast<uint64_t>(i * 0x9e3779b97f4a7c15ULL));
42+
return keys;
43+
}
44+
45+
std::vector<std::string> makeStringKeys(size_t size)
46+
{
47+
std::vector<std::string> keys;
48+
keys.reserve(size);
49+
for (size_t i = 0; i < size; ++i)
50+
keys.push_back("countmin-key-" + std::to_string(i * 2654435761ULL));
51+
return keys;
52+
}
53+
54+
int64_t totalStringBytes(const std::vector<std::string> & keys)
55+
{
56+
int64_t bytes = 0;
57+
for (const auto & key : keys)
58+
bytes += static_cast<int64_t>(key.size());
59+
return bytes;
60+
}
61+
62+
void BM_CountMinUpdateUInt64(benchmark::State & state)
63+
{
64+
const auto keys = makeUInt64Keys(static_cast<size_t>(state.range(0)));
65+
for (auto _ : state)
66+
{
67+
state.PauseTiming();
68+
Sketch sketch(NUM_HASHES, NUM_BUCKETS);
69+
state.ResumeTiming();
70+
71+
for (const auto key : keys)
72+
sketch.update(&key, sizeof(key), 1);
73+
74+
benchmark::DoNotOptimize(sketch.get_total_weight());
75+
}
76+
77+
state.SetItemsProcessed(state.iterations() * static_cast<int64_t>(keys.size()));
78+
state.SetBytesProcessed(state.iterations() * static_cast<int64_t>(keys.size() * sizeof(uint64_t)));
79+
}
80+
81+
void BM_CountMinUpdateStringBytes(benchmark::State & state)
82+
{
83+
const auto keys = makeStringKeys(static_cast<size_t>(state.range(0)));
84+
const auto bytes_per_iteration = totalStringBytes(keys);
85+
86+
for (auto _ : state)
87+
{
88+
state.PauseTiming();
89+
Sketch sketch(NUM_HASHES, NUM_BUCKETS);
90+
state.ResumeTiming();
91+
92+
for (const auto & key : keys)
93+
sketch.update(key.data(), key.size(), 1);
94+
95+
benchmark::DoNotOptimize(sketch.get_total_weight());
96+
}
97+
98+
state.SetItemsProcessed(state.iterations() * static_cast<int64_t>(keys.size()));
99+
state.SetBytesProcessed(state.iterations() * bytes_per_iteration);
100+
}
101+
102+
void BM_CountMinEstimateUInt64(benchmark::State & state)
103+
{
104+
const auto keys = makeUInt64Keys(static_cast<size_t>(state.range(0)));
105+
Sketch sketch(NUM_HASHES, NUM_BUCKETS);
106+
for (const auto key : keys)
107+
sketch.update(&key, sizeof(key), 1);
108+
109+
uint64_t sum = 0;
110+
for (auto _ : state)
111+
{
112+
for (const auto key : keys)
113+
sum += sketch.get_estimate(&key, sizeof(key));
114+
115+
benchmark::DoNotOptimize(sum);
116+
}
117+
118+
state.SetItemsProcessed(state.iterations() * static_cast<int64_t>(keys.size()));
119+
state.SetBytesProcessed(state.iterations() * static_cast<int64_t>(keys.size() * sizeof(uint64_t)));
120+
}
121+
122+
void BM_CountMinEstimateStringBytes(benchmark::State & state)
123+
{
124+
const auto keys = makeStringKeys(static_cast<size_t>(state.range(0)));
125+
const auto bytes_per_iteration = totalStringBytes(keys);
126+
127+
Sketch sketch(NUM_HASHES, NUM_BUCKETS);
128+
for (const auto & key : keys)
129+
sketch.update(key.data(), key.size(), 1);
130+
131+
uint64_t sum = 0;
132+
for (auto _ : state)
133+
{
134+
for (const auto & key : keys)
135+
sum += sketch.get_estimate(key.data(), key.size());
136+
137+
benchmark::DoNotOptimize(sum);
138+
}
139+
140+
state.SetItemsProcessed(state.iterations() * static_cast<int64_t>(keys.size()));
141+
state.SetBytesProcessed(state.iterations() * bytes_per_iteration);
142+
}
143+
144+
}
145+
146+
BENCHMARK(BM_CountMinUpdateUInt64)->RangeMultiplier(8)->Range(1024, 65536);
147+
BENCHMARK(BM_CountMinUpdateStringBytes)->RangeMultiplier(8)->Range(1024, 65536);
148+
BENCHMARK(BM_CountMinEstimateUInt64)->RangeMultiplier(8)->Range(1024, 65536);
149+
BENCHMARK(BM_CountMinEstimateStringBytes)->RangeMultiplier(8)->Range(1024, 65536);

0 commit comments

Comments
 (0)