是时候从C++ priority_queue中弹出元素了

Time to pop element from a C++ priority_queue

本文关键字:元素 queue C++ priority      更新时间:2023-10-16

我有以下问题:我正在实现一种算法,该算法本质上是执行扫描(https://en.wikipedia.org/wiki/Sweep_line_algorithm)时间以更新数据结构。对于相关的时间点,我生成适当的事件,并将其存储在std::priority_queue中:在每个步骤中,我以最小的时间值弹出事件,对其进行处理,并在必要时将其他一些事件推送到队列中。不幸的是,我的代码运行得很慢。我使用 gprof 看了一下,似乎该算法在 std::priority_queue::pop 中花费了大约 60% 的执行时间。有没有办法提高操作效率?

编辑:循环基本上看起来像这样:

typedef std::priority_queue<Event, vector<Event>, greater<Event> > EventQueue;
while(!events.empty())
{
  Event e = events.top();
  events.pop();
  const DirectedEdge &edge = e.current_edge->get_edge();
  if(e.type == Event::LEAVING)
  {
    Event ee = e;
    ee.type = Event::ENTERING;
    ++ee.current_edge;
    if(!ee.current_edge)
    {
      ee.path->set_arrival_time(ee.time);
    }
    else
    {
      ee.current_edge->set_departure_time(ee.time);
      ee.time += get_delay(ee.current_edge->get_edge());
      events.push(ee);
    }
  }
  else
  { 
    Event ee = e;
    ee.type = Event::LEAVING;
    const FlowFloat time = queues[edge.get_index()].insert_traveler(e.time, e.path);
    ee.time = time;
    events.push(ee);
  }
}

如果您使用的是符合 C++11 的编译器,请尝试将 move 构造函数/运算符添加到 Event 类中,因为 priority_queue 对元素执行大量操作,如果它可以移动而不是复制,它会快得多。这当然取决于Event的定义方式:如果它是 POD 类型,则不会获得任何收益;如果移动运算符不比复制快任何操作,也不会获得任何好处。