这个算法是指数加权移动平均(EWMA, Exponentially Weighted Moving Average),常用于对随时间变化的数据做“平滑处理”(给近期数据更高权重,远期数据更低权重)。
核心要素说明
-
参数
a:- 取值范围是
0 ≤ a ≤ 1,它是“折扣系数”(也叫平滑系数)。 a越接近 1:旧数据的权重越高,新数据的影响越小,结果越平滑;a越接近 0:新数据的权重越高,结果更“紧跟”最新数据。
- 取值范围是
-
函数逻辑
estimate_rate_pps(instant_rate, old_rate): 这个函数的作用是结合“当前瞬时速率(instant_rate)”和“历史旧速率(old_rate)”,计算新的平滑后速率。 公式为:(1-a)是“当前瞬时速率”的权重;a是“历史旧速率”的权重;- 本质是加权平均:用固定的系数
a对新、旧数据做“折扣式”融合。
举个例子
比如 a=0.8,当前瞬时速率是 10,旧速率是 5:
能看到:旧数据(5)的权重更高,新速率更贴近旧值。
这是EWMA算法的具体代码实现,核心是把“折扣系数a”和“平滑逻辑”落地成代码,同时用“定点数(fixed point)”处理数值(避免浮点精度问题)。
逐行拆解逻辑
-
计算折扣系数
afpoint a = to_fixed_point(dur) / WINDOW;dur:通常是“时间间隔”(比如两次数据更新的时间差);to_fixed_point(dur):把dur转成定点数格式(用整数模拟小数,避免浮点误差);WINDOW:是一个“时间窗口常数”(比如希望让数据在多长时间内完成平滑);- 所以
a的本质是:a = 时间间隔 / 时间窗口,保证0 ≤ a ≤ 1(符合EWMA的参数要求)。
-
初始化新速率
fpoint new_rate = old_rate;先把“新速率”初始化为“旧速率”,后续再根据当前值调整。
-
根据当前值调整新速率 核心是让新速率向“当前瞬时速率(rate_current)”靠近,靠近的幅度由
a控制:if (old_rate > to_fixed_point(rate_current)) { // 旧速率 > 当前速率 → 新速率 = 旧速率 - a*(旧速率-当前速率) new_rate -= a * to_int(old_rate - to_fixed_point(rate_current)); } else { // 旧速率 ≤ 当前速率 → 新速率 = 旧速率 + a*(当前速率-旧速率) new_rate += a * to_int(to_fixed_point(rate_current) - old_rate); }to_fixed_point(rate_current):把“当前瞬时速率”转成定点数;to_int(...):把定点数的差值转成整数(配合定点数运算规则);- 本质等价于之前的EWMA公式:
new_rate = (1-a)*rate_current + a*old_rate(只是拆成“加减”形式实现)。
-
返回新速率
return new_rate;
总结
这段代码是**“定点数版的EWMA实现”**:用a = 时间间隔/时间窗口控制平滑幅度,通过“旧速率向当前速率逐步靠近”的逻辑,实现数据的指数加权平滑,同时用定点数避免浮点运算的精度问题。