Speed up DfgGraph::addGraph

Append whole lists in one go, rather than going item by item.
This commit is contained in:
Geza Lore 2022-10-08 12:05:30 +01:00
parent c033a0d7c8
commit ff49f797e5
3 changed files with 35 additions and 4 deletions

View File

@ -40,10 +40,22 @@ DfgGraph::~DfgGraph() {
}
void DfgGraph::addGraph(DfgGraph& other) {
other.forEachVertex([&](DfgVertex& vtx) {
other.removeVertex(vtx);
this->addVertex(vtx);
});
m_size += other.m_size;
other.m_size = 0;
const auto moveVertexList = [this](V3List<DfgVertex*>& src, V3List<DfgVertex*>& dst) {
if (DfgVertex* vtxp = src.begin()) {
vtxp->m_verticesEnt.moveAppend(src, dst, vtxp);
do {
vtxp->m_graphp = this;
vtxp = vtxp->verticesNext();
} while (vtxp);
}
};
moveVertexList(other.m_varVertices, m_varVertices);
moveVertexList(other.m_constVertices, m_constVertices);
moveVertexList(other.m_opVertices, m_opVertices);
}
std::vector<std::unique_ptr<DfgGraph>> DfgGraph::splitIntoComponents(std::string label) {

View File

@ -536,6 +536,7 @@ public:
//------------------------------------------------------------------------------
void DfgGraph::addVertex(DfgVertex& vtx) {
// Note: changes here need to be replicated in DfgGraph::addGraph
++m_size;
if (vtx.is<DfgConst>()) {
vtx.m_verticesEnt.pushBack(m_constVertices, &vtx);
@ -548,6 +549,7 @@ void DfgGraph::addVertex(DfgVertex& vtx) {
}
void DfgGraph::removeVertex(DfgVertex& vtx) {
// Note: changes here need to be replicated in DfgGraph::addGraph
--m_size;
if (vtx.is<DfgConst>()) {
vtx.m_verticesEnt.unlink(m_constVertices, &vtx);

View File

@ -119,6 +119,23 @@ public:
}
m_prevp = m_nextp = nullptr;
}
// Remove all nodes from 'oldListr', append them to 'newListr'. 'this' must be a member of the
// object at 'selfp', and 'selfp' must be the head of the list in 'oldListr'.
void moveAppend(V3List<T>& oldListr, V3List<T>& newListr, T selfp) {
UASSERT(selfp == oldListr.m_headp, "Must be head of list to use 'moveAppend'");
const size_t offset = (size_t)(uint8_t*)(this) - (size_t)(uint8_t*)(selfp);
const T headp = selfp;
const T tailp = oldListr.m_tailp;
oldListr.reset();
if (newListr.empty()) {
newListr.m_headp = headp;
newListr.m_tailp = tailp;
} else {
baseToListEnt(newListr.m_tailp, offset)->m_nextp = headp;
m_prevp = newListr.m_tailp;
newListr.m_tailp = tailp;
}
}
};
//============================================================================