簡體   English   中英

C ++中的遞歸函數和性能

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM