Improve shared_vector::push_back

push_back now allocates additional space
in powers of 2 up to 1k elements, then
in blocks of 1k elements.
This commit is contained in:
Michael Davidsaver
2013-06-11 17:40:59 -04:00
parent 70c9a7c18f
commit 4e749cc8be
2 changed files with 55 additions and 2 deletions

View File

@@ -6,6 +6,8 @@
#include <stdexcept>
#include <iterator>
#include <cassert>
#include "pv/sharedPtr.h"
namespace epics { namespace pvData {
@@ -423,9 +425,34 @@ public:
// Modifications
private:
void _push_resize() {
if(this->m_count==this->m_total || !this->unique()) {
size_t next;
if(this->m_total<1024) {
// round m_total+1 up to the next power of 2
next = this->m_total;
next |= next >> 1;
next |= next >> 2;
next |= next >> 4;
next |= next >> 8;
next++;
} else {
// pad m_total up to the next multiple of 1024
next = this->m_total+1024;
next &= ~0x3ff;
}
assert(next > this->m_total);
reserve(next);
}
resize(this->size()+1);
}
public:
void push_back(param_type v)
{
resize(this->size()+1);
_push_resize();
back() = v;
}

View File

@@ -329,6 +329,31 @@ static void testCapacity()
testOk1(vect[1]==124);
}
static void testPush()
{
epics::pvData::shared_vector<int> vect;
testDiag("Test push_back optimizations");
size_t nallocs = 0;
size_t cap = vect.capacity();
for(size_t s=0; s<16*1024; s++) {
vect.push_back(s);
if(cap!=vect.capacity()) {
nallocs++;
cap = vect.capacity();
}
}
testDiag("push_back %ld times caused %ld re-allocations",
(unsigned long)vect.size(),
(unsigned long)nallocs);
testOk1(nallocs==26);
}
static void testVoid()
{
testDiag("Test vecter cast to/from void");
@@ -409,7 +434,7 @@ static void testWeak()
MAIN(testSharedVector)
{
testPlan(121);
testPlan(122);
testDiag("Tests for shared_vector");
testDiag("sizeof(shared_vector<int>)=%lu",
@@ -422,6 +447,7 @@ MAIN(testSharedVector)
testShare();
testConst();
testSlice();
testPush();
testVoid();
testNonPOD();
testWeak();