@leaveye
2022-03-22T06:10:10.000000Z
字数 1718
阅读 382
代码 样本 速度
class SpeedEstimator {constexpr static const float epsilon = 1E-24;constexpr static const float duration_default_multiplier = 50;using timeValue = uint64_t;public:SpeedEstimator() : SpeedEstimator(0) {}explicit SpeedEstimator(timeValue now, timeValue interval = 20, timeValue mean_duration = 0) {init(now, interval, mean_duration);}void init(timeValue now, timeValue interval, timeValue mean_duration) {_ts_state = now, _interval = interval;_n = 0, _d = epsilon;if (mean_duration != 0) _decay = 1 - interval / (float) mean_duration;else _decay = 1 - 1 / duration_default_multiplier;_duration = interval / (1 - _decay);}void reset(timeValue now) {init(now, _interval, _duration);}timeValue duration() const {return (timeValue) std::lround(_duration);}float avg() const {assert(_d >= epsilon || _d <= -epsilon);return 1000 * _n / _d;}void update(timeValue now, size_t size) {update(now, (float) size);}void update(timeValue now, float state) {auto period = (float) (now - _ts_state);if (period < _interval) {_state = state;} else if (period < _duration + _interval * 4) {auto stage = state / period * _interval;while (period >= _interval) {_d *= _decay, _d += _interval;_n *= _decay, _n += stage;state -= stage, period -= _interval;}_ts_state = now - period;_state = state;} else {state *= _duration / period;_d = _duration;_n = state * (_duration / period);_ts_state = now;_state = 0;}}void update(size_t size) {update((float) size);}void update(float state) {update(_ts_state + _interval, state);}void acc(timeValue now, ssize_t count) {acc(now, (float) count);}void acc(timeValue now, float diff) {update(now, _state + diff);}void acc(size_t count) {acc((float) count);}void acc(float diff) {_state += diff;}void accNext(size_t count) {accNext((float) count);}void accNext(float diff) {update(_state + diff);}protected:float _n = 0, _d = 1E-24;float _state = 0;float _decay{};timeValue _ts_state{}, _interval{};float _duration{};};
