make_heap vs priority_queue 每帧需要一次时的效率

make_heap vs priority_queue efficiency when needed once per frame

我试图找到有关此特定用途的信息,但找不到。

在模拟软件(就像视频游戏)中,我正在构建一个事件管理器,它根据事件创建者提交的值对事件进行优先级排序。事件队列每帧将被解析一次,其中的所有事件都将被处理,因此每个新帧都以一个空队列开始。

现在我有两个选项来存储事件并设置它们的优先级:

  1. 使用 std::priority_queue,这将始终保持 list/vector/container 的优先级,然后在需要时简单地解析它;
  2. 使用非优先容器,当我需要解析它时,在它之前调用 make_heap 以便它使事件优先。

因为我每帧只分析一次事件列表,所以我不需要一直优先考虑它。

我的问题是:在这种情况下,make_heap 是否比始终保持容器最新更有效?还是取决于我管理的数据量?还是我想多了?

std::map<priority, event> 可能是一种权衡:根据优先级进行插入。 std::map 的插入是或顺序 n log(n) 并始终保持其优先级。

在需要事件的时候,不需要处理,只是迭代。

渐近没有区别:

  1. 在有序集合中插入N次是O(N log N)。

  2. 对 N 个元素的无序集合进行排序是 O(N log N)。

因此,select 最快解决方案的最佳方法是同时实施并检查真实数据。

我认为将事件存储在诸如 std::vector 的容器中并在最后对它们进行排序会更快,因为快速添加和帧准备不会使 CPU 缓存失效,这可能发生在 "long" 和非平凡的 O(log N) 插入 std::priority_queuestd::map.

还将事件存储在简单的容器中 (std::vector) 并在需要时处理它们(排序等)对我来说看起来更合乎逻辑。

始终保持队列优先需要 Θ(n log n) 时间。制作堆需要 Θ(n) 时间。后来这两种方法都需要同时Θ(n log n),按照排序的顺序一个一个的提取元素。所以 make_heap 显然是更好的选择。但是由于这两种方法在需要时都相当于对您的输入进行排序,因此 quicksort 是更好的选择。