Skip to content

Commit

Permalink
add bench and fix (#755)
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos authored Aug 14, 2024
1 parent 1138159 commit 66a1442
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 8 deletions.
6 changes: 3 additions & 3 deletions include/ylt/metric/counter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ class basic_static_counter : public static_metric {
// static counter, contains a static labels with atomic value.
basic_static_counter(std::string name, std::string help,
std::map<std::string, std::string> labels,
size_t dupli_count = 2)
uint32_t dupli_count = 2)
: static_metric(MetricType::Counter, std::move(name), std::move(help),
std::move(labels)) {
init_thread_local(dupli_count);
}

void init_thread_local(size_t dupli_count) {
void init_thread_local(uint32_t dupli_count) {
if (dupli_count > 0) {
dupli_count_ = dupli_count;
default_label_value_ = {dupli_count};
Expand Down Expand Up @@ -163,7 +163,7 @@ class basic_static_counter : public static_metric {
}

thread_local_value<value_type> default_label_value_;
size_t dupli_count_ = 2;
uint32_t dupli_count_ = 2;
};

template <size_t N>
Expand Down
10 changes: 5 additions & 5 deletions include/ylt/metric/thread_local_value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
#include <vector>

namespace ylt::metric {
inline size_t get_round_index(size_t size) {
static std::atomic<size_t> round = 0;
static thread_local size_t index = round++;
inline uint32_t get_round_index(uint32_t size) {
static std::atomic<uint32_t> round = 0;
static thread_local uint32_t index = round++;
return index % size;
}
template <typename value_type>
class thread_local_value {
public:
thread_local_value(size_t dupli_count = std::thread::hardware_concurrency())
thread_local_value(uint32_t dupli_count = std::thread::hardware_concurrency())
: duplicates_(dupli_count) {}

~thread_local_value() {
Expand Down Expand Up @@ -73,7 +73,7 @@ class thread_local_value {
value_type reset() { return update(0); }

auto &local_value() {
static thread_local auto index = get_round_index(duplicates_.size());
auto index = get_round_index(duplicates_.size());
return get_value(index);
}

Expand Down
4 changes: 4 additions & 0 deletions src/metric/benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output/benchmark)

add_executable(metric_benchmark
main.cpp)
107 changes: 107 additions & 0 deletions src/metric/benchmark/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#include <array>
#include <atomic>
#include <chrono>
#include <iostream>
#include <random>
#include <thread>

#include "ylt/metric.hpp"

using namespace std::chrono_literals;
using namespace ylt::metric;

void bench_static_counter(size_t thd_num, std::chrono::seconds duration,
size_t dupli_count = 2) {
counter_t counter("qps", "", dupli_count);
std::vector<std::thread> vec;
std::atomic<bool> stop = false;
auto start = std::chrono::system_clock::now();
for (size_t i = 0; i < thd_num; i++) {
vec.push_back(std::thread([&] {
while (!stop) {
counter.inc(1);
}
}));
}

std::this_thread::sleep_for(duration);
stop = true;
auto end = std::chrono::system_clock::now();

auto elaps =
std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
.count();

double seconds = double(elaps) / 1000;

auto qps = counter.value() / seconds;
std::cout << "duplicate count: " << dupli_count << ", thd num: " << thd_num
<< ", qps: " << (uint64_t)qps << "\n";

for (auto& thd : vec) {
thd.join();
}
}

auto get_random(size_t range = 10000) {
thread_local std::default_random_engine gen(std::time(nullptr));
std::uniform_int_distribution<> distr(1, range);
return distr(gen);
}

void bench_dynamic_counter(size_t thd_num, std::chrono::seconds duration,
size_t dupli_count = 2) {
dynamic_counter_t counter("qps2", "", {"url", "code"}, dupli_count);
std::atomic<bool> stop = false;
std::vector<std::thread> vec;
std::array<std::string, 2> arr{"/test", "200"};
auto start = std::chrono::system_clock::now();
for (size_t i = 0; i < thd_num; i++) {
vec.push_back(std::thread([&, i] {
while (!stop) {
counter.inc({"/test", std::to_string(get_random())}, 1);
}
}));
}
std::this_thread::sleep_for(duration);
stop = true;
auto end = std::chrono::system_clock::now();

auto elaps =
std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
.count();

double seconds = double(elaps) / 1000;
std::cout << "run " << elaps << "ms, " << seconds << " seconds\n";

size_t total = 0;
for (size_t i = 0; i < 10000; i++) {
total += counter.value({"/test", std::to_string(i)});
}
auto qps = total / seconds;
std::cout << "duplicate count: " << dupli_count << ", thd num: " << thd_num
<< ", qps: " << (int64_t)qps << "\n";
for (auto& thd : vec) {
thd.join();
}
}

int main() {
bench_static_counter(1, 5s);
bench_static_counter(2, 5s);
bench_static_counter(8, 5s);
bench_static_counter(16, 5s);
bench_static_counter(32, 5s);
bench_static_counter(96, 5s);
bench_static_counter(32, 5s, 32);
bench_static_counter(96, 5s, 96);

bench_dynamic_counter(1, 5s);
bench_dynamic_counter(2, 5s);
bench_dynamic_counter(8, 5s);
bench_dynamic_counter(16, 5s);
bench_dynamic_counter(32, 5s);
bench_dynamic_counter(96, 10s);
bench_dynamic_counter(32, 5s, 32);
bench_dynamic_counter(96, 5s, 96);
}

0 comments on commit 66a1442

Please sign in to comment.