[英]Recursive function and performance in 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,但是如果上面的條件是正確的,那么這個問題就少了。
這很浪費。
if (refSet.find(id) == refSet.end())
refSet.insert(id);
插入之前,無需檢查某物是否是集合的成員,只需插入即可。
refSet.insert(id);
也就是說,這並不是數量級的改進。
這也可能有幫助
const auto& ids = kid.neighbors(id, 7);
取決於neighbors
返回的內容,但看起來您正在復制某些集合或其他集合。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.