Performance 用于处理未来事件的查找结构(基于时间)
我正在寻找一个有效的数据结构,这将允许我提示事件。。。也就是说,我将有一个应用程序,在执行过程中的任何时候,都有可能为将来的执行点引发一个事件。。。比如:Performance 用于处理未来事件的查找结构(基于时间),performance,language-agnostic,data-structures,advanced-queuing,Performance,Language Agnostic,Data Structures,Advanced Queuing,我正在寻找一个有效的数据结构,这将允许我提示事件。。。也就是说,我将有一个应用程序,在执行过程中的任何时候,都有可能为将来的执行点引发一个事件。。。比如: t=20:420秒后,出现一个 t=25:在13秒内,B出现 t=27:735秒后,C出现 所以我希望有一个数据结构,在那里我可以在未来的任何时间放入任何事件,在那里我可以获取并(通过这样做)删除所有到期事件。。。另外,如果我能够从数据结构中删除一个事件(因为它被取消了),那么这将是一个加号。。。虽然不太重要,因为我可以简单地将其标记为
- t=20:420秒后,出现一个
- t=25:在13秒内,B出现
- t=27:735秒后,C出现
编辑:
- 更具体地说:我想这里的n大约是100K-1M,我想我可能会有大约1-100个事件/秒
- t没有什么特别重要的。。。这只是为了说明未来的事件可以随时“排队”
谢谢
back2dos我相信您正在寻找一个以事件发生时间戳为优先级的事件(时间戳越低优先级越高) 只需对您的用例进行一点说明: 。。。我可以在任何情况下 将来的任何时候 使用事件发生时的时间戳,将insertWithPriority插入优先级队列。这将是O(lgN) 。。。以及我能去的地方和(通过做) 因此)删除所有到期事件 您需要反复调用getTop(具有最低时间戳的gets事件),以收集感兴趣的时间之前的所有元素 。。。另外,如果我是的话,我会有一个加分 能够从中删除事件 数据结构(因为它是 取消)。。。不太重要 尽管如此,因为我可以简单地将其标记为 取消
这是可能的,但由于重新平衡,这将是O(lgN)。如果您的事件有一个明确定义的上限(例如,未来2天内没有事件发生),您只需将数组从“时间开始”起以秒为索引即可。 数组的值是该偏移量处的事件列表 列出或删除是非常有效的—只需找到您希望列出或删除的时间的偏移量,并获取或重新初始化偏移量之后索引指向的数组 如果您的事件可以无限延伸到未来,那么您自己使用hashmap从偏移量到事件列表的想法是最好的,有一个转折点-拥有一个已知偏移量的排序列表(无论您希望如何实现),这样您将有非常高效的查找(例如,您不必循环映射中的每个键) 您不需要从已知偏移量列表中删除任何内容,因此不存在重新平衡的问题—您只需从hashmap指向的数组中删除即可
此外,从你的问题来看,似乎不清楚是否有必要知道“t”——事件发生的时间。如果需要了解,请将其作为活动的一部分存储。但是对事件发生时间的引用应该相对于某个起始点是绝对的(如果它是一个范围无限的hashmap,那么可以使用历元秒,如果事件有我列出的第一个数组解决方案中的边界,那么应该使用“#自范围开始的秒数”-例如,从昨天开始。N有多大?与其他事情相比,您需要多长时间插入和删除项目?如果这超过总执行时间的10%,并且如果N通常超过100(例如)也许,也许是时候关注big-O了。我见过一些程序,它们使用奇特的容器算法实现优先级队列,分配迭代器、散列映射、堆等,并将所有时间都花在创建和发布抽象对象上,其中中值队列长度为3
补充:好的,由于N~10^6,频率为~100hz,您可能需要某种二叉树或带有O(log(N))的堆插入/删除时间。如果您愿意将1%的CPU时间用于此操作,即10^6微秒*1%/100=10^2微秒/操作。这应该一点也不困难,因为如果典型的搜索深度为20,每次比较约50ns,则执行搜索需要约1微秒。请确保保持简单,不要把所有内容都包罗万象在抽象数据类型中。您不必太担心分配/释放树节点所花费的时间,因为每个操作只分配/释放一个节点。无需经常进行重新平衡,比如每1000次操作后才进行重新平衡。如果您可以批量收集插入,然后以随机顺序插入,则可能会阻止避免树变得太不平衡。如果您的许多事件是同时发生的,您可以在时间代码中添加少量噪声,以防止树的某些部分变得更像线性列表。好的,我要感谢大家的回答-非常有趣且有用。:) PriorityQueue绝对是我一直在寻找的正确术语-谢谢。 现在一切都是关于实现的 以下是我的想法: 假设N是队列的大小,M是处理时每个时间戳的平均事件量(“并发”事件)(事件的密度不会均匀分布,“遥远的未来”会更大)