#pragma once #include "../Base/global_include.h" #include "global.h" namespace Psc { class Base_Statistics { protected: size_t start_time; [[nodiscard]] static uint64_t get_current_ms() { using namespace std::chrono; return duration_cast( steady_clock::now().time_since_epoch() ).count(); } public: Base_Statistics() : start_time(get_current_ms()) {} virtual JSON to_json() const = 0; virtual ~Base_Statistics() = default; unsigned int get_start_time() const { return start_time; } }; // Speed Statistics 类,继承自 Base_Statistics\ // 单位B/s class Speed_Statistics : public Base_Statistics { public: double cur_total{}; double instant_speed{}; double average_speed{}; size_t times{}; Speed_Statistics& operator+=(const Speed_Statistics& rhs) { this->cur_total += rhs.cur_total; this->instant_speed += rhs.instant_speed; this->average_speed += rhs.average_speed; this->times += rhs.times; return *this; } Speed_Statistics() { clear(); } void clear() { cur_total = 0; instant_speed = -1; average_speed = -1; times = 0; } [[nodiscard]] JSON to_json() const override { JSON ret = JSON::object(); // Ret_J(cur_total) Ret_J(instant_speed) Ret_J(average_speed) Ret_J(times) return ret; } [[nodiscard]] std::string to_string() const { return VAR_STR_4(instant_speed, average_speed, cur_total, times); } void update(unsigned int len) { cur_total += static_cast(len); auto true_period_ms = get_current_ms() - start_time; size_t period = 100; // 100 ms 统计一次 times++; if (instant_speed == -1) { instant_speed = 0; start_time = get_current_ms(); } if (true_period_ms > period) { // 字节/秒 instant_speed = cur_total / true_period_ms * 1000; // 转换成 KB/s //instant_speed /= 1024.0f; // 平均速度 double average_times = 10.0f; if (average_speed >= 0) { average_speed = average_speed * (average_times - 1.0f) / average_times + instant_speed * (1.0f) / average_times; } else { average_speed = instant_speed; } start_time = get_current_ms(); cur_total = 0; } } }; // Value Statistics 类,继承自 Base_Statistics class Value_Statistics : public Base_Statistics { public: double max{}; double min{}; double average{}; double instant{}; size_t times = 0; [[nodiscard]] JSON to_json() const override { JSON ret = JSON::object(); Ret_J(max) Ret_J(min) Ret_J(average) Ret_J(instant) return ret; } [[nodiscard]] std::string to_string() const { return VAR_STR_5(min, max, average, instant, times); } Value_Statistics() { clear(); } void clear() { max = std::numeric_limits::min(); min = std::numeric_limits::max(); average = -1; instant = 0; times = 0; } void update(double value) { max = std::max(max, value); min = std::min(min, value); double average_times = 10.0f; // 平均取近十次 instant = value; if (average != -1) { average = average * (average_times - 1.0f) / average_times + instant * (1.0f) / average_times; } else { average = instant; } times++; } }; // Probability Statistics 类,继承自 Base_Statistics class Probability_Statistics : public Base_Statistics { public: unsigned short instant{}; unsigned short average{}; unsigned int count{}; // 成功次数 unsigned int total{}; // 总次数 unsigned int total_max{}; // 总次数 [[nodiscard]] JSON to_json() const override { JSON ret = JSON::object(); Ret_J(instant) Ret_J(average) Ret_J(count) Ret_J(total) Ret_J(total_max) return ret; } Probability_Statistics() { clear(); } void clear() { instant = 0; average = 0; count = 0; total = 0; total_max = 10; } // 成功调用 update(1) // 失败调用 update(-1) // 可以调用 update(n) n > 0 表示连续成功n次 // 可以调用 update(n) n < 0 表示连续失败n次 void update(int count_change) { if (count_change == 0) { count_change = -1; } if (count_change > 0) { count += count_change; total += count_change; } else if (count_change < 0) { total += -count_change; } if (total < total_max) return; // 至少累计 100 次才统计一次 // instant 概率 (0-1000) instant = (count * 1000) / total; if (average == 0) { average = instant; } else { // 平滑平均,base = 8 average = ((average << 3) - average + instant) >> 3; } // 清零重新统计一批 count = 0; total = 0; } }; } // namespace Psc