常规更新
This commit is contained in:
+143
-170
@@ -1,207 +1,180 @@
|
||||
#pragma once
|
||||
#include "../Base/global_include.h"
|
||||
#include "global.h"
|
||||
|
||||
namespace Psc {
|
||||
class Base_Statistics {
|
||||
protected:
|
||||
size_t start_time;
|
||||
|
||||
class Base_Statistics {
|
||||
protected:
|
||||
uint64_t start_time;
|
||||
[[nodiscard]] static uint64_t get_current_ms() {
|
||||
using namespace std::chrono;
|
||||
return duration_cast<milliseconds>(steady_clock::now().time_since_epoch())
|
||||
.count();
|
||||
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()) {
|
||||
}
|
||||
|
||||
virtual JSON to_json() const = 0;
|
||||
|
||||
public:
|
||||
Base_Statistics() : start_time(get_current_ms()) {}
|
||||
[[nodiscard]] 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:
|
||||
[[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{};
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
Speed_Statistics() { clear(); }
|
||||
|
||||
void clear() {
|
||||
cur_total = 0;
|
||||
instant_speed = -1;
|
||||
average_speed = -1;
|
||||
times = 0;
|
||||
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(cur_total)
|
||||
Ret_J(instant_speed)
|
||||
Ret_J(average_speed)
|
||||
Ret_J(times)
|
||||
return ret;
|
||||
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);
|
||||
return VAR_STR_4(instant_speed, average_speed, cur_total, times);
|
||||
}
|
||||
|
||||
void update(unsigned int len) {
|
||||
cur_total += static_cast<double>(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;
|
||||
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;
|
||||
}
|
||||
|
||||
start_time = get_current_ms();
|
||||
cur_total = 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
// Value Statistics 类,继承自 Base_Statistics
|
||||
class Value_Statistics : public Base_Statistics {
|
||||
public:
|
||||
};
|
||||
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;
|
||||
size_t times{};
|
||||
bool init{};
|
||||
Value_Statistics() {
|
||||
clear();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string to_string() const {
|
||||
return VAR_STR_5(min, max, average, instant, times);
|
||||
}
|
||||
|
||||
Value_Statistics() { clear(); }
|
||||
|
||||
void clear() {
|
||||
max = std::numeric_limits<double>::min();
|
||||
min = std::numeric_limits<double>::max();
|
||||
average = -1;
|
||||
instant = 0;
|
||||
times = 0;
|
||||
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) {
|
||||
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++;
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
// Probability Statistics 类,继承自 Base_Statistics
|
||||
class Probability_Statistics : public Base_Statistics {
|
||||
public:
|
||||
};
|
||||
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;
|
||||
unsigned int count{};
|
||||
unsigned int total{};
|
||||
unsigned int total_max{};
|
||||
Probability_Statistics() {
|
||||
clear();
|
||||
}
|
||||
|
||||
Probability_Statistics() { clear(); }
|
||||
|
||||
void clear() {
|
||||
instant = 0;
|
||||
average = 0;
|
||||
count = 0;
|
||||
total = 0;
|
||||
total_max = 10;
|
||||
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);
|
||||
}
|
||||
|
||||
// 成功调用 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;
|
||||
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;
|
||||
}
|
||||
};
|
||||
} // namespace Psc
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user