make_heap vs priority_queue 每帧需要一次时的效率
make_heap vs priority_queue efficiency when needed once per frame
我试图找到有关此特定用途的信息,但找不到。
在模拟软件(就像视频游戏)中,我正在构建一个事件管理器,它根据事件创建者提交的值对事件进行优先级排序。事件队列每帧将被解析一次,其中的所有事件都将被处理,因此每个新帧都以一个空队列开始。
现在我有两个选项来存储事件并设置它们的优先级:
- 使用 std::priority_queue,这将始终保持 list/vector/container 的优先级,然后在需要时简单地解析它;
- 使用非优先容器,当我需要解析它时,在它之前调用 make_heap 以便它使事件优先。
因为我每帧只分析一次事件列表,所以我不需要一直优先考虑它。
我的问题是:在这种情况下,make_heap 是否比始终保持容器最新更有效?还是取决于我管理的数据量?还是我想多了?
std::map<priority, event>
可能是一种权衡:根据优先级进行插入。 std::map
的插入是或顺序 n log(n)
并始终保持其优先级。
在需要事件的时候,不需要处理,只是迭代。
渐近没有区别:
在有序集合中插入N次是O(N log N)。
对 N 个元素的无序集合进行排序是 O(N log N)。
因此,select 最快解决方案的最佳方法是同时实施并检查真实数据。
我认为将事件存储在诸如 std::vector
的容器中并在最后对它们进行排序会更快,因为快速添加和帧准备不会使 CPU 缓存失效,这可能发生在 "long" 和非平凡的 O(log N) 插入 std::priority_queue
或 std::map
.
还将事件存储在简单的容器中 (std::vector
) 并在需要时处理它们(排序等)对我来说看起来更合乎逻辑。
始终保持队列优先需要 Θ(n log n)
时间。制作堆需要 Θ(n)
时间。后来这两种方法都需要同时Θ(n log n)
,按照排序的顺序一个一个的提取元素。所以 make_heap
显然是更好的选择。但是由于这两种方法在需要时都相当于对您的输入进行排序,因此 quicksort
是更好的选择。
我试图找到有关此特定用途的信息,但找不到。
在模拟软件(就像视频游戏)中,我正在构建一个事件管理器,它根据事件创建者提交的值对事件进行优先级排序。事件队列每帧将被解析一次,其中的所有事件都将被处理,因此每个新帧都以一个空队列开始。
现在我有两个选项来存储事件并设置它们的优先级:
- 使用 std::priority_queue,这将始终保持 list/vector/container 的优先级,然后在需要时简单地解析它;
- 使用非优先容器,当我需要解析它时,在它之前调用 make_heap 以便它使事件优先。
因为我每帧只分析一次事件列表,所以我不需要一直优先考虑它。
我的问题是:在这种情况下,make_heap 是否比始终保持容器最新更有效?还是取决于我管理的数据量?还是我想多了?
std::map<priority, event>
可能是一种权衡:根据优先级进行插入。 std::map
的插入是或顺序 n log(n)
并始终保持其优先级。
在需要事件的时候,不需要处理,只是迭代。
渐近没有区别:
在有序集合中插入N次是O(N log N)。
对 N 个元素的无序集合进行排序是 O(N log N)。
因此,select 最快解决方案的最佳方法是同时实施并检查真实数据。
我认为将事件存储在诸如 std::vector
的容器中并在最后对它们进行排序会更快,因为快速添加和帧准备不会使 CPU 缓存失效,这可能发生在 "long" 和非平凡的 O(log N) 插入 std::priority_queue
或 std::map
.
还将事件存储在简单的容器中 (std::vector
) 并在需要时处理它们(排序等)对我来说看起来更合乎逻辑。
始终保持队列优先需要 Θ(n log n)
时间。制作堆需要 Θ(n)
时间。后来这两种方法都需要同时Θ(n log n)
,按照排序的顺序一个一个的提取元素。所以 make_heap
显然是更好的选择。但是由于这两种方法在需要时都相当于对您的输入进行排序,因此 quicksort
是更好的选择。