我有一个图表(adjacency_list(listS,vecS,bidirectionalS,VertexVal)),我需要删除100,000多个节点。每个节点还包含2个64位整数和另一个64位整数的结构。下面代码中发生的guid检查是检查结构中的第一个整数。
根据VTune,在我的笔记本电脑(i7 2.7GHz,16GB RAM)上大约需要88秒。
以下是删除节点的方法:
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显示boost :: remove_vertex()调用需要88.145秒。有没有更有效的方法来删除这些顶点?
答案 0 :(得分:8)
在你的删除分支中你重新tie()
迭代器:
boost::tie(vi, vi_end) = boost::vertices(m_graph);
这将导致每次重新启动循环时重新启动循环。这完全 Schlemiel The Painter。
我会发现您是否可以信任remove_vertex
不会触发重新分配。如果是这样,它很容易修复。否则,您需要基于索引器的循环而不是基于迭代器的循环。或者你也许能够处理原始容器(不过,我记得这是一个私人成员)。
更新使用vecS
作为顶点的容器会导致性能下降:
如果
VertexList
的{{1}}模板参数为adjacency_list
,则此操作将使图的所有顶点描述符,边描述符和迭代器无效。 < ...> 如果您需要经常使用vecS
功能,remove_vertex()
选择器是listS
模板参数的更好选择。
VertexList
(-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
(-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
(在评论中感谢filtered_graph
)
@cv_and_he
您可以清楚地看到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
的删除速度 ,但生成 很多 慢。
答案 1 :(得分:2)
我能够使用Boost序列化例程将图形成功序列化为字符串,解析字符串并删除我不需要的节点并对已修改的字符串进行反序列化。对于图表中的200,000个节点和需要删除的100,000个节点,我能够在不到2秒的时间内成功完成操作。
对于我的特定用例,每个顶点有3个64位整数。当需要删除时,我将其中2个整数标记为0。一个有效的顶点永远不会有0.当点清理图形时 - 要删除“已删除”的顶点,我遵循上面的逻辑。
在下面的代码中,removeDeletedNodes()执行字符串解析并删除顶点并映射边数。
答案 2 :(得分:0)
看到更多的Vtune数据会很有趣。
我的经验是,删除数以万计的小对象时,默认的Microsoft分配器可能是一个很大的瓶颈。你的Vtune图表在删除或免费中显示了很多时间吗?
如果是这样,请考虑切换到第三方分配器。据说Nedmalloc很好:http://www.nedprod.com/programs/portable/nedmalloc/
Google有一个tcmalloc,它几乎在每个平台上都非常受欢迎,并且比内置分配器快得多。 https://code.google.com/p/gperftools/ tcmalloc不是Windows的插件。