【问题标题】:Java Priority Queue with Efficient delete(...) (or update)具有高效删除(...)(或更新)的 Java 优先级队列
【发布时间】:2016-01-31 20:05:18
【问题描述】:

我正在开发一个事件驱动的模拟器,我的事件都在 java.util.PriorityQueue 中。问题是事件在运行时会被重新安排很多次,并且由于库存 PriorityQueue 中没有更新优先级,我删除了元素并重新插入新的优先级。

这行得通,但性能(太)差,而且不能很好地扩展。 JVisualVM 的分析器告诉我 99% 的时间都浪费在 pq.delete(...) 中。

是否有一种 PQ 的实现可以有效地更新优先级,或者至少有一种方法,其中 delete(...) 比库存中的 O(N) 更有效?

我尝试了一个斐波那契堆,它在某个点上运行得更快,但也不能很好地扩展。

【问题讨论】:

  • 您期望每个元素与轮询相比大约有多少更新?比如,你认为一个元素的优先级在被轮询之前平均会改变多少次?
  • 很多很多次。我相信有几十到几百。
  • 这与您预期的堆大小相比如何?如果它是大小的一个常数因子,那么完全忘记堆并只使用优先级哈希图可能会更快。这将为您提供 O(1) 更新和 O(N) pollMin/pollMax。是否更快由您决定
  • 可以尝试使用 TreeSet 或 TreeMap 代替 PriorityQueue 吗?
  • 我会试试的,Mshnik,然后返回结果。谢谢!

标签: java queue


【解决方案1】:

这是一个队列解决方案:不要从队列中移除,而是维护一个单独的队列。每当您需要调整优先级时,您只需形成一个新队列并用它替换原来的队列。

为避免潜在的并发问题,您应该在某个时间点阻止读取器/写入器以重新分配队列。

【讨论】:

    猜你喜欢
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    • 2015-01-15
    • 1970-01-01
    • 2023-04-02
    相关资源
    最近更新 更多