From 12a1a357843fe57fbed200f5a46de8b121cd349e Mon Sep 17 00:00:00 2001 From: EvilSpirit Date: Mon, 24 Oct 2016 22:28:44 +0700 Subject: [PATCH] Reserve space upfront when possible, to avoid re-allocations. --- src/dsc.h | 24 ++++++++++++++++++------ src/generate.cpp | 3 +++ src/srf/boolean.cpp | 2 ++ src/srf/curve.cpp | 1 + src/srf/surface.cpp | 4 +++- src/undoredo.cpp | 5 +++++ 6 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/dsc.h b/src/dsc.h index fbe1dc09..bd5c7f35 100644 --- a/src/dsc.h +++ b/src/dsc.h @@ -162,9 +162,9 @@ public: int n; int elemsAllocated; - void AllocForOneMore() { - if(n >= elemsAllocated) { - elemsAllocated = (elemsAllocated + 32)*2; + void ReserveMore(int howMuch) { + if(n + howMuch > elemsAllocated) { + elemsAllocated = n + howMuch; T *newElem = (T *)MemAlloc((size_t)elemsAllocated*sizeof(elem[0])); for(int i = 0; i < n; i++) { new(&newElem[i]) T(std::move(elem[i])); @@ -175,6 +175,12 @@ public: } } + void AllocForOneMore() { + if(n >= elemsAllocated) { + ReserveMore((elemsAllocated + 32)*2 - n); + } + } + void Add(const T *t) { AllocForOneMore(); new(&elem[n++]) T(*t); @@ -285,9 +291,9 @@ public: return t->h; } - void Add(T *t) { - if(n >= elemsAllocated) { - elemsAllocated = (elemsAllocated + 32)*2; + void ReserveMore(int howMuch) { + if(n + howMuch > elemsAllocated) { + elemsAllocated = n + howMuch; T *newElem = (T *)MemAlloc((size_t)elemsAllocated*sizeof(elem[0])); for(int i = 0; i < n; i++) { new(&newElem[i]) T(std::move(elem[i])); @@ -296,7 +302,13 @@ public: MemFree(elem); elem = newElem; } + } + void Add(T *t) { + if(n >= elemsAllocated) { + ReserveMore((elemsAllocated + 32)*2 - n); + } + int first = 0, last = n; // We know that we must insert within the closed interval [first,last] while(first != last) { diff --git a/src/generate.cpp b/src/generate.cpp index 81795f89..98a6617e 100644 --- a/src/generate.cpp +++ b/src/generate.cpp @@ -217,7 +217,10 @@ void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox) // Don't lose our numerical guesses when we regenerate. IdList prev = {}; SK.param.MoveSelfInto(&prev); + SK.param.ReserveMore(prev.n); + int oldEntityCount = SK.entity.n; SK.entity.Clear(); + SK.entity.ReserveMore(oldEntityCount); for(i = 0; i < SK.groupOrder.n; i++) { Group *g = SK.GetGroup(SK.groupOrder.elem[i]); diff --git a/src/srf/boolean.cpp b/src/srf/boolean.cpp index 844d1db9..cc763a26 100644 --- a/src/srf/boolean.cpp +++ b/src/srf/boolean.cpp @@ -664,6 +664,7 @@ void SShell::MakeFromAssemblyOf(SShell *a, SShell *b) { // First, copy over all the curves. Note which shell (a or b) each curve // came from, but assign it a new ID. + curve.ReserveMore(a->curve.n + b->curve.n); SCurve *c, cn; for(i = 0; i < 2; i++) { ab = (i == 0) ? a : b; @@ -677,6 +678,7 @@ void SShell::MakeFromAssemblyOf(SShell *a, SShell *b) { } // Likewise copy over all the surfaces. + surface.ReserveMore(a->surface.n + b->surface.n); SSurface *s, sn; for(i = 0; i < 2; i++) { ab = (i == 0) ? a : b; diff --git a/src/srf/curve.cpp b/src/srf/curve.cpp index b5b3366d..5a8f1a26 100644 --- a/src/srf/curve.cpp +++ b/src/srf/curve.cpp @@ -741,6 +741,7 @@ SCurve SCurve::FromTransformationOf(SCurve *a, Vector t, ret.surfB = a->surfB; SCurvePt *p; + ret.pts.ReserveMore(a->pts.n); for(p = a->pts.First(); p; p = a->pts.NextAfter(p)) { SCurvePt pp = *p; if(needScale) { diff --git a/src/srf/surface.cpp b/src/srf/surface.cpp index 21c628e1..fdd1c504 100644 --- a/src/srf/surface.cpp +++ b/src/srf/surface.cpp @@ -165,6 +165,7 @@ SSurface SSurface::FromTransformationOf(SSurface *a, Vector t, Quaternion q, dou if(includingTrims) { STrimBy *stb; + ret.trim.ReserveMore(a->trim.n); for(stb = a->trim.First(); stb; stb = a->trim.NextAfter(stb)) { STrimBy n = *stb; if(needScale) { @@ -834,7 +835,7 @@ void SShell::MakeFromTransformationOf(SShell *a, Vector t, Quaternion q, double scale) { booleanFailed = false; - + surface.ReserveMore(a->surface.n); SSurface *s; for(s = a->surface.First(); s; s = a->surface.NextAfter(s)) { SSurface n; @@ -842,6 +843,7 @@ void SShell::MakeFromTransformationOf(SShell *a, surface.Add(&n); // keeping the old ID } + curve.ReserveMore(a->curve.n); SCurve *c; for(c = a->curve.First(); c; c = a->curve.NextAfter(c)) { SCurve n; diff --git a/src/undoredo.cpp b/src/undoredo.cpp index 638100e9..92fbb983 100644 --- a/src/undoredo.cpp +++ b/src/undoredo.cpp @@ -47,6 +47,7 @@ void SolveSpaceUI::PushFromCurrentOnto(UndoStack *uk) { UndoState *ut = &(uk->d[uk->write]); *ut = {}; + ut->group.ReserveMore(SK.group.n); for(i = 0; i < SK.group.n; i++) { Group *src = &(SK.group.elem[i]); Group dest = *src; @@ -76,17 +77,21 @@ void SolveSpaceUI::PushFromCurrentOnto(UndoStack *uk) { for(i = 0; i < SK.groupOrder.n; i++) { ut->groupOrder.Add(&(SK.groupOrder.elem[i])); } + ut->request.ReserveMore(SK.request.n); for(i = 0; i < SK.request.n; i++) { ut->request.Add(&(SK.request.elem[i])); } + ut->constraint.ReserveMore(SK.constraint.n); for(i = 0; i < SK.constraint.n; i++) { Constraint *src = &(SK.constraint.elem[i]); Constraint dest = *src; ut->constraint.Add(&dest); } + ut->param.ReserveMore(SK.param.n); for(i = 0; i < SK.param.n; i++) { ut->param.Add(&(SK.param.elem[i])); } + ut->style.ReserveMore(SK.style.n); for(i = 0; i < SK.style.n; i++) { ut->style.Add(&(SK.style.elem[i])); }