From 6cf765a4e33b9898fb07b247ed9db1b3e63808b3 Mon Sep 17 00:00:00 2001 From: jfa Date: Sat, 16 Dec 2023 00:57:45 +0000 Subject: [PATCH] [bos #39269] SHAPER is too slow compared to GEOM. Try keeping std::map in parallel with std::vector for fast access to indices. --- src/Model/Model_Objects.cpp | 49 ++++++++++++++++++++++++++++++------- src/Model/Model_Objects.h | 1 + 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index 41b019b9b..ddefa90a2 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -107,6 +107,7 @@ void Model_Objects::setOwner(DocumentPtr theDoc) TDF_LabelList aNoUpdated; synchronizeFeatures(aNoUpdated, true, false, true, true); myHistory.clear(); + myHistoryMap.clear(); } Model_Objects::~Model_Objects() @@ -138,6 +139,7 @@ Model_Objects::~Model_Objects() myFolders.UnBind(aFoldersIter.Key()); } myHistory.clear(); + myHistoryMap.clear(); aLoop->activateFlushes(isActive); // erase update, because features are destroyed and update should not performed for them anywhere aLoop->eraseMessages(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); @@ -374,6 +376,7 @@ void Model_Objects::eraseAllFeatures() kCreator->sendDeleted(myDoc, ModelAPI_Feature::group()); myFeatures.Clear(); // just remove features without modification of DS myHistory.clear(); + myHistoryMap.clear(); } void Model_Objects::moveFeature(FeaturePtr theMoved, FeaturePtr theAfterThis) @@ -445,6 +448,10 @@ void Model_Objects::clearHistory(ObjectPtr theObj) myHistory.find(aResultGroup); if (aHIter != myHistory.end()) myHistory.erase(aHIter); // erase from map => this means that it is not synchronized + std::map >::iterator aHIterMap = + myHistoryMap.find(aResultGroup); + if (aHIterMap != myHistoryMap.end()) + myHistoryMap.erase(aHIterMap); // erase from map => this means that it is not synchronized } } } @@ -452,10 +459,17 @@ void Model_Objects::clearHistory(ObjectPtr theObj) void Model_Objects::createHistory(const std::string& theGroupID) { - std::map >::iterator aHIter = myHistory.find(theGroupID); + std::map >::iterator aHIter = + myHistory.find(theGroupID); + std::map >::iterator aHIterMap = + myHistoryMap.find(theGroupID); if (aHIter == myHistory.end()) { std::vector aResult; std::vector aResultOutOfFolder; + std::map aResultMap; + std::map aResultOutOfFolderMap; + int aResultCounter = 0; + int aResultOutOfFolderCounter = 0; FeaturePtr aLastFeatureInFolder; // iterate the array of references and get feature by feature from the array bool isFeature = theGroupID == ModelAPI_Feature::group(); @@ -471,9 +485,11 @@ void Model_Objects::createHistory(const std::string& theGroupID) if (isFeature) { // here may be also disabled features if (!isSub && aFeature->isInHistory()) { aResult.push_back(aFeature); + aResultMap[aFeature] = aResultCounter++; // the feature is out of the folders if (aLastFeatureInFolder.get() == NULL) aResultOutOfFolder.push_back(aFeature); + aResultOutOfFolderMap[aFeature] = aResultOutOfFolderCounter++; } } else if (!aFeature->isDisabled()) { // iterate all results of not-disabled feature // construction results of sub-features should not be in the tree @@ -487,6 +503,7 @@ void Model_Objects::createHistory(const std::string& theGroupID) if (aRes->groupName() != theGroupID) break; // feature have only same group results if (!aRes->isDisabled() && aRes->isInHistory() && !aRes->isConcealed()) { aResult.push_back(*aRIter); + aResultMap[*aRIter] = aResultCounter++; } } } @@ -503,8 +520,11 @@ void Model_Objects::createHistory(const std::string& theGroupID) // store folder information for the Features group only if (isFeature || isFolder) { aResult.push_back(aFolder); - if (!isFolder) + aResultMap[aFolder] = aResultCounter++; + if (!isFolder) { aResultOutOfFolder.push_back(aFolder); + aResultOutOfFolderMap[aFolder] = aResultOutOfFolderCounter++; + } } // get the last feature in the folder @@ -519,11 +539,14 @@ void Model_Objects::createHistory(const std::string& theGroupID) // to be sure that isConcealed did not update the history (issue 1089) during the iteration if (myHistory.find(theGroupID) == myHistory.end()) { myHistory[theGroupID] = aResult; + myHistoryMap[theGroupID] = aResultMap; // store the features placed out of any folder const std::string& anOutOfFolderGroupID = groupNameFoldering(theGroupID, true); - if (!anOutOfFolderGroupID.empty()) + if (!anOutOfFolderGroupID.empty()) { myHistory[anOutOfFolderGroupID] = aResultOutOfFolder; + myHistoryMap[anOutOfFolderGroupID] = aResultOutOfFolderMap; + } } } } @@ -544,6 +567,15 @@ void Model_Objects::updateHistory(const std::string theGroup) if (!anOutOfFolderGroupID.empty()) myHistory.erase(anOutOfFolderGroupID); } + std::map >::iterator aHIterMap = myHistoryMap.find(theGroup); + if (aHIterMap != myHistoryMap.end()) { + myHistoryMap.erase(aHIterMap); // erase from map => this means that it is not synchronized + + // erase history for the group of objects placed out of any folder + const std::string& anOutOfFolderGroupID = groupNameFoldering(theGroup, true); + if (!anOutOfFolderGroupID.empty()) + myHistoryMap.erase(anOutOfFolderGroupID); + } } const ObjectPtr& Model_Objects::folder(TDF_Label theLabel) const @@ -672,12 +704,10 @@ const int Model_Objects::index(std::shared_ptr theObject, if (theAllowFolder && !groupNameFoldering(aGroup, theAllowFolder).empty()) aGroup = groupNameFoldering(aGroup, theAllowFolder); - std::vector& allObjs = myHistory[aGroup]; - std::vector::iterator anObjIter = allObjs.begin(); // iterate to search object - for(int anIndex = 0; anObjIter != allObjs.end(); anObjIter++, anIndex++) { - if ((*anObjIter) == theObject) - return anIndex; - } + std::map& allObjs = myHistoryMap[aGroup]; + std::map::const_iterator aFound = allObjs.find(theObject); + if (aFound != allObjs.end()) + return (*aFound).second; // not found return -1; } @@ -987,6 +1017,7 @@ void Model_Objects::synchronizeFeatures( if (!theUpdated.IsEmpty()) { // this means there is no control what was modified => remove history cash myHistory.clear(); + myHistoryMap.clear(); } if (!theExecuteFeatures) diff --git a/src/Model/Model_Objects.h b/src/Model/Model_Objects.h index 627d3900e..1331b80c2 100644 --- a/src/Model/Model_Objects.h +++ b/src/Model/Model_Objects.h @@ -308,6 +308,7 @@ class Model_Objects /// Map from group id to the array that contains all objects located in history. /// Each array is updated by demand from scratch, by browsing all the features in the history. std::map > myHistory; + std::map > myHistoryMap; friend class Model_Document; friend class Model_Session; -- 2.39.2