From 1d73d2485b3f0f93e3fe7b0ab519291d9851af37 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Fri, 16 Aug 2024 17:28:59 +0800 Subject: [PATCH] [metric][benchmark]Add more benchmark (#759) --- CMakeLists.txt | 2 +- include/ylt/metric/counter.hpp | 2 +- include/ylt/metric/summary.hpp | 13 +- include/ylt/version.hpp | 2 +- src/metric/benchmark/main.cpp | 214 +++++++++++++++++++++++++++++---- 5 files changed, 205 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 97b692367..49c805f33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.15) project(yaLanTingLibs - VERSION 0.3.6 + VERSION 0.3.7 DESCRIPTION "yaLanTingLibs" HOMEPAGE_URL "https://github.com/alibaba/yalantinglibs" LANGUAGES CXX diff --git a/include/ylt/metric/counter.hpp b/include/ylt/metric/counter.hpp index 90130987f..db9eb953d 100644 --- a/include/ylt/metric/counter.hpp +++ b/include/ylt/metric/counter.hpp @@ -286,7 +286,7 @@ class basic_dynamic_counter : public dynamic_metric { auto now = std::chrono::system_clock::now(); std::lock_guard lock(mtx_); - std::erase_if(value_map_, [&now](auto &pair) { + std::erase_if(value_map_, [&now](auto &pair) mutable { bool r = std::chrono::duration_cast( now - pair.second.get_created_time()) .count() >= ylt_label_max_age.count(); diff --git a/include/ylt/metric/summary.hpp b/include/ylt/metric/summary.hpp index bf013980e..270d1b66c 100644 --- a/include/ylt/metric/summary.hpp +++ b/include/ylt/metric/summary.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include "detail/time_window_quantiles.hpp" @@ -67,7 +68,8 @@ class summary_t : public static_metric { } void observe(double value) { - if (block_->sample_queue_.size_approx() >= 20000000) { + int64_t max_limit = (std::min)(ylt_label_capacity, (int64_t)1000000); + if (block_->sample_queue_.size_approx() >= max_limit) { g_summary_failed_count++; return; } @@ -197,7 +199,7 @@ class summary_t : public static_metric { async_simple::coro::Lazy start(std::shared_ptr block) { double sample; - size_t count = 1000000; + size_t count = 100000; while (!block->stop_) { size_t index = 0; while (block->sample_queue_.try_dequeue(sample)) { @@ -282,7 +284,8 @@ class basic_dynamic_summary : public dynamic_metric { } void observe(std::array labels_value, double value) { - if (labels_block_->sample_queue_.size_approx() >= 20000000) { + int64_t max_limit = (std::min)(ylt_label_capacity, (int64_t)1000000); + if (labels_block_->sample_queue_.size_approx() >= max_limit) { g_summary_failed_count++; return; } @@ -295,6 +298,8 @@ class basic_dynamic_summary : public dynamic_metric { } } + size_t size_approx() { return labels_block_->sample_queue_.size_approx(); } + async_simple::coro::Lazy> get_rates( const std::array &labels_value, double &sum, uint64_t &count) { @@ -350,7 +355,7 @@ class basic_dynamic_summary : public dynamic_metric { async_simple::coro::Lazy start( std::shared_ptr> label_block) { summary_label_sample sample; - size_t count = 1000000; + size_t count = 100000; while (!label_block->stop_) { size_t index = 0; while (label_block->sample_queue_.try_dequeue(sample)) { diff --git a/include/ylt/version.hpp b/include/ylt/version.hpp index ad649d376..a88d64b1f 100644 --- a/include/ylt/version.hpp +++ b/include/ylt/version.hpp @@ -20,4 +20,4 @@ // YLT_VERSION % 100 is the sub-minor version // YLT_VERSION / 100 % 1000 is the minor version // YLT_VERSION / 100000 is the major version -#define YLT_VERSION 306 // 0.3.6 \ No newline at end of file +#define YLT_VERSION 307 // 0.3.7 \ No newline at end of file diff --git a/src/metric/benchmark/main.cpp b/src/metric/benchmark/main.cpp index af35ce47a..cb34cd0e9 100644 --- a/src/metric/benchmark/main.cpp +++ b/src/metric/benchmark/main.cpp @@ -10,8 +10,8 @@ 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) { +void bench_static_counter_qps(size_t thd_num, std::chrono::seconds duration, + size_t dupli_count = 2) { counter_t counter("qps", "", dupli_count); std::vector vec; std::atomic stop = false; @@ -49,8 +49,8 @@ auto get_random(size_t range = 10000) { return distr(gen); } -void bench_dynamic_counter(size_t thd_num, std::chrono::seconds duration, - size_t dupli_count = 2) { +void bench_dynamic_counter_qps(size_t thd_num, std::chrono::seconds duration, + size_t dupli_count = 2) { dynamic_counter_t counter("qps2", "", {"url", "code"}, dupli_count); std::atomic stop = false; std::vector vec; @@ -86,22 +86,194 @@ void bench_dynamic_counter(size_t thd_num, std::chrono::seconds duration, } } +void bench_many_metric_serialize(size_t COUNT, size_t LABEL_COUNT, + bool to_json = false) { + std::vector> vec; + for (size_t i = 0; i < COUNT; i++) { + auto counter = std::make_shared( + std::string("qps"), "", std::array{"url", "code"}); + for (size_t j = 0; j < LABEL_COUNT; j++) { + counter->inc({"test_label_value", std::to_string(j)}); + } + vec.push_back(counter); + } + + std::cout << "begin test\n"; + + std::string str; + + auto start = std::chrono::system_clock::now(); + if (to_json) { + str = manager_helper::serialize_to_json(vec); + } + else { + str = manager_helper::serialize(vec); + } + + auto end = std::chrono::system_clock::now(); + auto elaps = + std::chrono::duration_cast(end - start) + .count(); + std::cout << "string size: " << str.size() << ", " << elaps << "ms\n"; +} + +void bench_many_labels_serialize(size_t COUNT, bool to_json = false) { + dynamic_counter_t counter("qps2", "", {"url", "code"}); + std::string val(36, ' '); + for (size_t i = 0; i < COUNT; i++) { + strcpy(val.data(), std::to_string(i).data()); + counter.inc({"123e4567-e89b-12d3-a456-426614174000", val}); + } + + std::string str; + auto start = std::chrono::system_clock::now(); + if (to_json) { + counter.serialize_to_json(str); + } + else { + counter.serialize(str); + } + + auto end = std::chrono::system_clock::now(); + auto elaps = + std::chrono::duration_cast(end - start) + .count(); + std::cout << elaps << "ms\n"; + std::cout << "label value count: " << counter.label_value_count() + << " string size: " << str.size() << "\n"; +} + +void bench_many_labels_qps_summary(size_t thd_num, + std::chrono::seconds duration) { + dynamic_summary_2 summary( + "qps2", "", + summary_t::Quantiles{ + {0.5, 0.05}, {0.9, 0.01}, {0.95, 0.005}, {0.99, 0.001}}, + std::array{"method", "url"}); + std::atomic stop = false; + std::vector vec; + std::array arr{"/test", "200"}; + thread_local_value local_val(thd_num); + auto start = std::chrono::system_clock::now(); + std::string val(36, ' '); + for (size_t i = 0; i < thd_num; i++) { + vec.push_back(std::thread([&, i] { + while (!stop) { + strcpy(val.data(), std::to_string(i).data()); + summary.observe({"/test", std::to_string(get_random())}, + get_random(100)); + local_val.inc(); + } + })); + } + std::this_thread::sleep_for(duration); + stop = true; + auto end = std::chrono::system_clock::now(); + + auto elaps = + std::chrono::duration_cast(end - start) + .count(); + + double seconds = double(elaps) / 1000; + std::cout << "run " << elaps << "ms, " << seconds << " seconds\n"; + + auto qps = local_val.value() / seconds; + std::cout << "thd num: " << thd_num << ", qps: " << (int64_t)qps << "\n"; + for (auto& thd : vec) { + thd.join(); + } + + start = std::chrono::system_clock::now(); + size_t last = summary.size_approx(); + std::cout << "total size: " << last << "\n"; + while (true) { + std::this_thread::sleep_for(1s); + size_t current = summary.size_approx(); + if (current == 0) { + break; + } + + std::cout << last - current << "\n"; + last = current; + } + end = std::chrono::system_clock::now(); + elaps = std::chrono::duration_cast(end - start) + .count(); + std::cout << "consume " << elaps << "ms\n"; +} + +void bench_many_labels_serialize_summary(size_t COUNT, bool to_json = false) { + dynamic_summary_2 summary( + "qps2", "", + summary_t::Quantiles{ + {0.5, 0.05}, {0.9, 0.01}, {0.95, 0.005}, {0.99, 0.001}}, + std::array{"method", "url"}); + std::string val(36, ' '); + for (size_t i = 0; i < COUNT; i++) { + strcpy(val.data(), std::to_string(i).data()); + summary.observe({"123e4567-e89b-12d3-a456-426614174000", val}, + get_random(100)); + } + + std::string str; + auto start = std::chrono::system_clock::now(); + if (to_json) { + async_simple::coro::syncAwait(summary.serialize_to_json_async(str)); + } + else { + async_simple::coro::syncAwait(summary.serialize_async(str)); + } + + auto end = std::chrono::system_clock::now(); + auto elaps = + std::chrono::duration_cast(end - start) + .count(); + std::cout << elaps << "ms\n"; + std::cout << "label value count: " << summary.label_value_count() + << " string size: " << str.size() << "\n"; +} + 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); + bench_many_labels_serialize_summary(100000); + bench_many_labels_serialize_summary(1000000); + + bench_many_labels_serialize_summary(100000, true); + bench_many_labels_serialize_summary(1000000, true); + + bench_many_labels_qps_summary(1, 5s); + bench_many_labels_qps_summary(2, 5s); + bench_many_labels_qps_summary(8, 5s); + bench_many_labels_qps_summary(16, 5s); + bench_many_labels_qps_summary(32, 5s); + bench_many_labels_qps_summary(96, 5s); + + bench_many_labels_serialize(100000); + bench_many_labels_serialize(1000000); + bench_many_labels_serialize(10000000); + bench_many_labels_serialize(100000, true); + bench_many_labels_serialize(1000000, true); + bench_many_labels_serialize(10000000, true); + + bench_many_metric_serialize(100000, 10); + bench_many_metric_serialize(1000000, 10); + bench_many_metric_serialize(100000, 10, true); + bench_many_metric_serialize(1000000, 10, true); + + bench_static_counter_qps(1, 5s); + bench_static_counter_qps(2, 5s); + bench_static_counter_qps(8, 5s); + bench_static_counter_qps(16, 5s); + bench_static_counter_qps(32, 5s); + bench_static_counter_qps(96, 5s); + bench_static_counter_qps(32, 5s, 32); + bench_static_counter_qps(96, 5s, 96); + + bench_dynamic_counter_qps(1, 5s); + bench_dynamic_counter_qps(2, 5s); + bench_dynamic_counter_qps(8, 5s); + bench_dynamic_counter_qps(16, 5s); + bench_dynamic_counter_qps(32, 5s); + bench_dynamic_counter_qps(96, 10s); + bench_dynamic_counter_qps(32, 5s, 32); + bench_dynamic_counter_qps(96, 5s, 96); }