Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
346 views
in Technique[技术] by (71.8m points)

c++ - Remove 100,000+ nodes from a Boost graph

I have a graph ( adjacency_list (listS, vecS, bidirectionalS, VertexVal) ) in which I need to delete 100,000+ nodes. Each node also contains a structure of 2 64-bit integers and another 64-bit integer. The guid check that happens in the code below is checking 1st integer in the structure.

On my laptop ( i7 2.7GHz, 16GB RAM ) it takes about 88 seconds according to VTune.

Following is how I delete the nodes:

  vertex_iterator vi,vi_end;
  boost::tie(vi, vi_end) = boost::vertices(m_graph);
  while (vi!=vi_end) {
    if (m_graph[*vi].guid.part1 == 0) {
      boost::remove_vertex(*vi,m_graph);
      boost::tie(vi, vi_end) = boost::vertices(m_graph);
    } else 
      ++vi;
  }

Vtune shows that the boost::remove_vertex() call takes 88.145 seconds. Is there a more efficient way to delete these vertices? Vtune data for boost::remove_vertex_dispatch(). This is the breakdown of the 88 seconds

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

In your removal branch you re-tie() the iterators:

boost::tie(vi, vi_end) = boost::vertices(m_graph);

This will cause the loop to restart every time you restart the loop. This is exactly Schlemiel The Painter.

I'll find out whether you can trust remove_vertex not triggering a reallocation. If so, it's easily fixed. Otherwise, you'd want an indexer-based loop instead of iterator-based. Or you might be able to work on the raw container (it's a private member, though, as I remember).

Update Using vecS as the container for vertices is going to cause bad performance here:

If the VertexList template parameter of the adjacency_list was vecS, then all vertex descriptors, edge descriptors, and iterators for the graph are invalidated by this operation. <...> If you need to make frequent use of the remove_vertex() function the listS selector is a much better choice for the VertexList template parameter.


This small benchmark test.cpp compares:

  • with -DSTABLE_IT (listS)

    $ ./stable 
    Generated 100000 vertices and 5000 edges in 14954ms
    The graph has a cycle? false
    starting selective removal...
    Done in 0ms
    After: 99032 vertices and 4916 edges
    
  • without -DSTABLE_IT (vecS)

    $ ./unstable 
    Generated 100000 vertices and 5000 edges in 76ms
    The graph has a cycle? false
    starting selective removal...
    Done in 396ms
    After: 99032 vertices and 4916 edges
    
  • using filtered_graph (thanks @cv_and_he in the comments)

    Generated 100000 vertices and 5000 edges in 15ms
    The graph has a cycle? false
    starting selective removal...
    Done in 0ms
    After: 99032 vertices and 4916 edges
    Done in 13ms
    

You can clearly see that removal is much faster for listS but generating is much slower.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...