这最容易由循环缓冲区处理。
循环缓冲区具有固定数量的元素和指向它的指针。您可以将一个元素添加到缓冲区,并且当您这样做时,您将指针递增到下一个元素。如果您通过了固定长度的缓冲区,您将从头开始。这是一种存储“最后 N 个”项目的空间和时间有效的方式。
现在,在您的情况下,您可以拥有一个包含 1,000 个计数器的循环缓冲区,每个计数器计算一毫秒内的消息数。添加所有 1,000 个计数器可以为您提供最后一秒的总计数。当然,您可以通过增量更新计数来优化报告部分,即从计数中减去插入时覆盖的数字,然后添加新数字。
然后,您可以拥有另一个具有 60 个插槽的循环缓冲区,并以整秒为单位计算消息的总数;每秒一次,您获取毫秒缓冲区的总计数并将计数写入分辨率为秒的缓冲区,等等。
这里类似 C 的伪代码:
int msecbuf[1000]; // initialized with zeroes
int secbuf[60]; // ditto
int msecptr = 0, secptr = 0;
int count = 0;
int msec_total_ctr = 0;
void msg_received() { count++; }
void every_msec() {
msec_total_ctr -= msecbuf[msecptr];
msecbuf[msecptr] = count;
msec_total_ctr += msecbuf[msecptr];
count = 0;
msecptr = (msecptr + 1) % 1000;
}
void every_sec() {
secbuf[secptr] = msec_total_ctr;
secptr = (secptr + 1) % 60;
}