如何有效地实现大量计时器
How to implement a large number of timers efficiently?
我正在用c++编写一个程序,该程序可能有数十万个对象,每个对象都有过期时间,也就是说,如果它们在一定时间内不活动,则应该删除它们。许多对象非常频繁地活动,新对象也非常迅速地创建。
我一直在犹豫该用什么方法。我一直在阅读有关亚洲计时器的文章,但我不太确定它们是否能很好地满足我的需求,如果能,又是如何满足的。我想到了两种方法:
-
我可以为每个对象创建一个死线计时器,并在对象执行某些操作时重置它。这意味着我将有成千上万个计时器。
-
我可以创建多个计时器队列,例如,30个计时器用于30秒的过期时间。第一个计时器用于剩余30秒生命周期的对象。如果它们在一秒钟内处于非活动状态,则将它们移动到对象的计时器队列中,并保留29秒的生命周期,依此类推。如果最后一个队列中的对象处于非活动状态一秒钟,则删除该对象。
第二种方法听起来更有效,但这是真的吗?如果Asio可以有效地处理大量计时器,那么第二种方法可能会浪费我的大量精力。我该怎么做呢?还是有更好的办法?
EDIT:我想我必须加上效率,我指的是更好的CPU利用率。在这里,内存使用是次要问题。
我将创建一个队列,根据要过期的剩余时间对对象进行排序。如果预期过期时间频繁,我会使用链表,否则使用数组,因为在列表中查找内容更快(但如果在对象本身而不是节点中保留对下一个和上一个对象的引用,则没关系)。
- 现在你只需要一个定时器的对象与最低过期时间。
- 当该定时器用完时,删除队列开头的对象,并为下一个对象准备定时器。
制作数字列表并给出定时器的逻辑。这是实现for timer最有效的方法,因为它消耗的内存更少。
我将采用第一种方法,并增加了一个变化,即只有当您尝试执行操作且截止日期已过时,您才会删除对象。它更容易实现,因为它是懒惰的,在某种意义上,你不计算计时器,直到你不得不(意思是当你试图使用对象)。
如果考虑到效率,无论何时删除对象,所做的工作都应该是相同的。
保存截止日期时间的内存将在每个截止日期8字节左右,这相当于64位系统上指针的大小(方法2所需)。
方法1的唯一风险是,如果你不经常使用它们,你可能会一次积累更多的对象。您可以通过定期扫描和删除对象来缓解这种情况。只要对象积累得不是太快,就可以相对不频繁地进行扫描。
如果不断地创建新对象并删除旧对象,那么考虑使用对象池,在程序启动时创建一堆对象。如果用完,动态增加对象的数量。按一定比例(10% - 25%)增加物体的数量,而不是一次增加一个。如果不再需要某个对象,则将其返回到对象池。如果需要考虑内存,请考虑使用一种算法来删除对象池中的对象。例如,它可以每隔5或10分钟删除75%不使用的对象。
要实现这一点,请考虑使用可用对象池列表和使用中列表。您的对象应该有一个初始化方法,可以调用该方法初始化现有对象。调用参数应该与构造函数非常相似。至于容器本身,您可能想尝试同时使用向量和链表,看看哪个更快。如果你的应用需要搜索对象,那么std::map或std::unordered_map将是更好的选择。当计时器唤醒时,可以使用迭代器遍历整个正在使用的列表。
至于计时器,你认为哪个会更快——让500,000个计时器唤醒并每秒做一次事情,还是让一个计时器每秒唤醒一次以遍历500,000个对象的列表以查看是否应该将对象返回到对象池?我认为很明显,使用一个计时器更有效率。我也很担心这50万个计时器现在或将来是否会在Windows上运行。我知道一些旧的windows操作系统肯定会崩溃。计时器应该多久唤醒一次?尝试使用1到5秒之间的值。这将是内存消耗与更长的唤醒时间之间的权衡。为更短的唤醒时间进行CPU节流。
你的第二种方法听起来像一些垃圾收集器所做的。微软的。net垃圾收集器被组织成几代,寿命短的对象进入第0代,寿命长的对象进入第1代,而寿命最长的对象进入第2代。
如果使用多线程,那么考虑每个线程使用一个对象池。每个对象池都有自己的计时器
- Linux的Cpp上的计时器
- 提升 ASIO 无法识别计时器对象
- 为左值和右值的包装器实现C++范围
- C++迭代器:实现迭代器类时出错
- 提升 asio 并发计时器取消问题与链
- 使用单体计时器的pthread_cond_timedwait有时会比预期晚超时
- 窗口中的微秒计时器
- C++回调计时器实现
- 是否可以仅使用标准 c++/c++11 实现不带"sleep"的计时器?
- 在C++线程内实现多个计时器的最安全方法
- 实现高分辨率计时器的最佳方法
- 改进了 C++ 中计时器(超时事件)的实现
- 在 C++11 中实现看门狗计时器
- 仅使用标准库实现等待计时器
- 如何在c++中使用boost实现与系统时间无关的计时器回调
- 如何有效地实现大量计时器
- 如何在c++中实现带间隔的计时器
- 如何在 C++ 的多线程环境中实现计时器
- 使用 boost::asio 实现事件计时器
- 在c++中实现计时器