algorithm - 如何实现随时间衰减的计数器?

标签 algorithm data-structures

专柜要求

我想实现一个特殊的计数器:所有增量操作在固定时间段(比如 30 天)后超时。

一个例子:

  • 第 0 天:计数器 = 0。TTL = 30 天
  • 第 1 天:递增计数器 (+1)
  • 第 2 天:递增计数器 (+1)
  • 第 3 天:计数器的值 == 2
  • 第 31 天:计数器的值 == 1
  • 第 32 天:计数器的值 == 0

天真的解决方案

一个天真的实现是维护一组时间戳,其中每个时间戳等于增量的时间。计数器的值等于集合减去所有超时的时间戳后的大小。

这个朴素的计数器有 O(n) 空间(集合的大小),有 O(n) 查找和 O(1) 插入。这些值是准确的。

更好的解决方案(对我来说)

交易速度和内存力确保准确性。

我想要一个具有 O(1) 查找和插入、O(1) 空间的计数器。准确度 < 准确。

或者,我会接受 O(log n) 空间和查找。

计数器表示应适合存储在数据库字段中,即,我应该能够快速更新和轮询计数器,而无需太多(反)序列化开销。

我本质上是在寻找一个类似于 HyperLogLog 计数器的计数器,但用于不同类型的近似计数:递减增量与不同元素的数量

我怎样才能实现这样的计数器?

最佳答案

如果您可以接受 24 小时粒度,那么您可以将计数器分到 k 个桶中,其中 k 是最长 TTL 中的天数。

递增是一个复杂度为 O(1) 的操作 - 只需递增具有索引 (k-TTL) 的存储桶中的值,以及当前总和。

读取是另一个 O(1) 操作,因为您只需读取当前总和。

每晚都会有一个 cronjob 从现在过期的桶中弹出(并在另一端添加一个值为 0 的桶),并将您的计数器减少该桶中的总和(这是一个后台任务,因此它不会影响您的插入或读取操作)

关于algorithm - 如何实现随时间衰减的计数器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42295046/

相关文章:

mysql - 各种锦标赛/竞赛类型(联赛、阶梯、单败/双败等)的数据结构

c++ - 如何从文件中读取哈夫曼树频率

java - 检测字符串是否具有唯一字符 : comparing my solution to "Cracking the Coding Interview?"

c++ - 根据某些特定规则对文本进行标记。 C++中的算法

algorithm - 基数排序的性能特点

algorithm - 尝试计算搜索词之间的相似度

algorithm - 比较Canny算法的轮廓结果和相似度

算法题..链表

php - 可以有效衡量趋势和受欢迎程度的数据库结构?

c++ - 在方阵中,每个单元格都是黑色或白色。设计一个算法来找到最大子正方形,使得所有 4 个边框都是黑色