c++ - C++中的递归函数和性能
问题描述
我是 C++ 新手,如果有人帮助我验证以下功能或帮助我改进它,我将不胜感激。
void RecursiveKnn(std::set<PointId> &refSet, const PointId &id, const KD3Index &kid, int const lvl)
{
if (refSet.find(id) == refSet.end())
refSet.insert(id);
if (lvl < m_knn)
{
auto ids = kid.neighbors(id, 7);
for (auto x : ids)
{
if (x == id)
continue;
RecursiveKnn(refSet, x, kid, lvl+1);
}
}
}
我编写了一个递归函数来运行和生成一组分层对象。基本上,从一个对象开始,获取下一个/附近的对象等等,以达到下一个级别。除此之外,我还想避免重复。级别限制在 3 - 4 级,预计不会再进一步。
这个函数被称为数百万次,并且需要永远运行。如果有人可以提出任何改进建议,我将不胜感激。在我的脑海中,我确信std::set
使用的数据结构不正确,但我不知道该使用什么。
编辑:原因,我发现功能有性能问题是这样的。起初我有一个带有 3 个嵌套 for 循环的函数。在合理的时间内工作。当我将其更改为递归函数时,该过程没有完成一个多小时。
解决方案
如果没有更多信息,我的猜测是多个 PointId 可以是具有相同 PointId 的邻居,即使存在父/子关系也是如此。
换句话说,此代码在有向无环图上执行深度优先搜索,但没有像典型的深度优先搜索那样检查重访。这意味着您将多次探索相同的节点,这是非常低效的。
改变
if (refSet.find(id) == refSet.end())
refSet.insert(id);
至
if (refSet.find(id) != refSet.end())
return;
refSet.insert(id);
此外,您应该使用 std::unordered_set 而不是 std::set ,但如果上述情况属实,那么这是一个较小的问题。
推荐阅读
- sql - 在 SQL Server 中的聚合函数之后过滤条件?
- javascript - 使用电子主进程流式传输大型本地媒体文件并在渲染器进程中处理它们的最佳方法
- python - Python sum over iterator 以避免内存问题
- java - 如何在两个不可旋转的矩形之间实现碰撞响应
- c++ - 从 C++ 中动态分配的数组中删除对象
- excel - 将数据从一个 Excel 工作簿复制到另一个
- django - 如何使用 django-easy-pdf 进行 RTL
- javascript - React - 如何从 json 文件有条件地设置 className
- ios - NavigationLink Swift UI 不显示视图
- c - 结构冻结的memset初始化