Files
CPP_Core/Core/Statistics/Statistics.h
T
2026-07-14 18:10:22 +08:00

181 lines
4.9 KiB
C++

#pragma once
#include "../Base/global_include.h"
#include "global.h"
namespace Psc {
class Base_Statistics {
protected:
uint64_t start_time;
[[nodiscard]] static uint64_t get_current_ms() {
using namespace std::chrono;
return static_cast<uint64_t>(duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count());
}
public:
Base_Statistics() : start_time(get_current_ms()) {}
[[nodiscard]] virtual JSON to_json() const = 0;
virtual ~Base_Statistics() = default;
[[nodiscard]] unsigned int get_start_time() const {
return static_cast<unsigned int>(start_time);
}
};
class Speed_Statistics : public Base_Statistics {
public:
double cur_total{};
double instant_speed{};
double average_speed{};
size_t times{};
bool init{};
Speed_Statistics() {
clear();
}
Speed_Statistics& operator+=(const Speed_Statistics& rhs) {
cur_total += rhs.cur_total;
instant_speed += rhs.instant_speed;
average_speed += rhs.average_speed;
times += rhs.times;
init = init || rhs.init;
return *this;
}
void clear() {
cur_total = 0.0;
instant_speed = 0.0;
average_speed = 0.0;
times = 0;
init = false;
start_time = get_current_ms();
}
[[nodiscard]] JSON to_json() const override {
JSON ret = JSON::object();
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) {
constexpr uint64_t period_ms = 100;
constexpr double average_times = 10.0;
const uint64_t now = get_current_ms();
cur_total += static_cast<double>(len);
++times;
const uint64_t true_period_ms = now - start_time;
if (true_period_ms <= period_ms) {
return;
}
instant_speed = cur_total / static_cast<double>(true_period_ms) * 1000.0;
if (init) {
average_speed = average_speed * (average_times - 1.0) / average_times + instant_speed / average_times;
}
else {
average_speed = instant_speed;
init = true;
}
start_time = now;
cur_total = 0.0;
}
};
class Value_Statistics : public Base_Statistics {
public:
double max{};
double min{};
double average{};
double instant{};
size_t times{};
bool init{};
Value_Statistics() {
clear();
}
void clear() {
max = 0.0;
min = 0.0;
average = 0.0;
instant = 0.0;
times = 0;
init = false;
}
[[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);
}
void update(double value) {
constexpr double average_times = 10.0;
instant = value;
if (!init) {
max = value;
min = value;
average = value;
init = true;
}
else {
max = std::max(max, value);
min = std::min(min, value);
average = average * (average_times - 1.0) / average_times + instant / average_times;
}
++times;
}
};
class Probability_Statistics : public Base_Statistics {
public:
unsigned short instant{};
unsigned short average{};
unsigned int count{};
unsigned int total{};
unsigned int total_max{};
Probability_Statistics() {
clear();
}
void clear() {
instant = 0;
average = 0;
count = 0;
total = 0;
total_max = 10;
}
[[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;
}
void update(bool value) {
value ? update(1) : update(-1);
}
void update(int count_change) {
if (count_change == 0) {
count_change = -1;
}
if (count_change > 0) {
const auto change = static_cast<unsigned int>(count_change);
count += change;
total += change;
}
else {
total += static_cast<unsigned int>(-static_cast<int64_t>(count_change));
}
if (total < total_max) {
return;
}
instant = static_cast<unsigned short>((count * 1000U) / total);
if (average == 0) {
average = instant;
}
else {
average = static_cast<unsigned short>(((static_cast<unsigned int>(average) << 3U) - average + instant) >> 3U);
}
count = 0;
total = 0;
}
};
}