返回介绍

尝试2:传送带设计方案

发布于 2024-08-18 11:54:28 字数 1915 浏览 0 评论 0 收藏 0

我们需要一个设计来解决前面提到的两个问题:

1.删除不再需要的数据。

2.更新事先算好的minute_count总和和hour_count变量总和。

我们打算这样做:我们会像传送带一样地使用list。当新数据在一端到达,我们会在总数上增加。当数据太陈旧,它会从另一端“掉落”,并且我们会从总数中减去它。

有几种方法可以实现这个传送带设计。一种方法是维护两个独立的list,一个用于过去一分钟的事件,一个用于过去一小时。当有新事件到达时,在两个列表中都增加一个拷贝。

这种方法很简单,但它效率并不高,因为它为每个事件创建了两个拷贝。

另一种方法是维护两个list,事件先会进入第一个列表(“最后一分钟里的事件”),然后这个列表会把数据传送给第二个列表(“最后一小时[但不含最后一分钟]里的事件”)。

这种“两阶段”传送带设计看上去更有效,所以让我们按这个方法实现。

实现两阶段传送带设计

让我们从列出类中的成员开始:

这个传送带设计的要点在于要能随时间的推移“切换”事件,使事件从minute_events移到hour_events,并且minute_count和hour_count相应地更新。要做到这一点,我们会创建一个叫做ShiftOldEvents()的辅助方法。当我们有了这个方法以后,这个类的剩余部分很容易实现:

明显,我们把所有的脏活儿都放到了ShiftOldEvents()里:

这样就完成了吗?

我们已经解决了前面提到了对性能的两点担心,并且我们的方案是可行的。对很多应用来讲,这个解决方案就足够好了。但它还是有些缺点的。

首先,这个设计很不灵活。假设我们希望保留过去24小时的计数。这可能需要改动大量的代码。你可能已经注意到了,ShiftOldEvents()是一个很集中的函数,在分钟与小时数据间做了微妙的互动。

其次,这个类占用的内存很大。假设你有一个高流量的服务,每分钟调用Add()函数100次。因为我们保留了过去一小时内所有的数据,所以这段代码可能会需要用到大约5MB的内存。

一般来讲,Add()被调用得越多,使用的内存就越多。在一个产品开发环境中,库使用大量不可预测的内存不是一件好事。最好不论Add()被调用得多频繁,MinuteHourCounter能用固定数量的内存。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文