From 04ac31cba061b1e0828245391a3d93496af8df70 Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 10 Oct 2017 00:51:25 +0200 Subject: [PATCH] make _getOutListRecursive much more efficient by avoiding to process objects multiple times --- src/App/DocumentObject.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/App/DocumentObject.cpp b/src/App/DocumentObject.cpp index c3a17b6cbf..68718150c8 100644 --- a/src/App/DocumentObject.cpp +++ b/src/App/DocumentObject.cpp @@ -241,7 +241,7 @@ std::vector DocumentObject::getInListRecursive(void) const return result; } -void _getOutListRecursive(std::vector& objSet, const DocumentObject* obj, const DocumentObject* checkObj, int depth) +void _getOutListRecursive(std::set& objSet, const DocumentObject* obj, const DocumentObject* checkObj, int depth) { for (const auto objIt : obj->getOutList()){ // if the check object is in the recursive inList we have a cycle! @@ -249,8 +249,11 @@ void _getOutListRecursive(std::vector& objSet, const DocumentOb std::cerr << "DocumentObject::getOutListRecursive(): cyclic dependency detected!" << std::endl; throw Base::RuntimeError("DocumentObject::getOutListRecursive(): cyclic dependency detected!"); } - objSet.push_back(objIt); - _getOutListRecursive(objSet, objIt, checkObj,depth-1); + + // if the element was already in the set then there is no need to process it again + auto pair = objSet.insert(objIt); + if (pair.second) + _getOutListRecursive(objSet, objIt, checkObj, depth-1); } } @@ -258,18 +261,14 @@ std::vector DocumentObject::getOutListRecursive(void) cons { // number of objects in document is a good estimate in result size int maxDepth = getDocument()->countObjects() + 2; - std::vector result; - result.reserve(maxDepth); + std::set result; // using a recursive helper to collect all OutLists _getOutListRecursive(result, this, this, maxDepth); - // remove duplicate entries and resize the vector - std::sort(result.begin(), result.end()); - auto newEnd = std::unique(result.begin(), result.end()); - result.resize(std::distance(result.begin(), newEnd)); - - return result; + std::vector array; + array.insert(array.begin(), result.begin(), result.end()); + return array; } DocumentObjectGroup* DocumentObject::getGroup() const