#include
#include
#include "uvector_11.h"
#include "stopwatch.h"
volatile int *ptr;
size_t BASE_FACT = 10;
template
void doConstruct()
{
for(std::size_t i=0; i!=2500000 * BASE_FACT; ++i) {
Tp tp(1000);
ptr = &tp[0];
}
}
template
void doConstructFill()
{
for(std::size_t i=0; i!=1000000 * BASE_FACT; ++i) {
Tp tp(1000, 0, typename Tp::allocator_type());
ptr = &tp[0];
}
}
template
void doCopyConstruct()
{
Tp vec(1000, 1);
for(std::size_t i=0; i!=1000000 * BASE_FACT; ++i) {
Tp a(vec);
ptr = &a[0];
}
}
template
void doAssignCopy()
{
Tp vec(1000, 1), a;
for(std::size_t i=0; i!=1000000 * BASE_FACT; ++i) {
a = vec;
ptr = &a[0];
}
}
template
void doAssignMove()
{
Tp vec(1000, 1), a;
for(std::size_t i=0; i!=100000000 * BASE_FACT; ++i) {
a = std::move(vec);
ptr = &a[0];
vec = std::move(a);
ptr = &vec[0];
}
}
template
void doPushback()
{
for(size_t iter=0; iter!=250000 * BASE_FACT; ++iter)
{
Tp vec;
for(std::size_t i=0; i!=1000; ++i)
vec.push_back(i);
ptr = &vec[0];
}
}
template
void doPushbackNInitialized()
{
for(size_t iter=0; iter!=100000 * BASE_FACT; ++iter)
{
Tp vec;
for(std::size_t i=0; i!=10; ++i)
vec.push_back(1000, i);
ptr = &vec[0];
}
}
template
void doPushbackNInitializedImpl()
{
for(size_t iter=0; iter!=100000 * BASE_FACT; ++iter)
{
Tp vec;
for(std::size_t i=0; i!=10; ++i)
vec.insert(vec.end(), 1000, i);
ptr = &vec[0];
}
}
template
void doPushbackNUninitialized()
{
for(size_t iter=0; iter!=100000 * BASE_FACT; ++iter)
{
Tp vec;
for(std::size_t i=0; i!=10; ++i)
vec.push_back_uninitialized(1000);
ptr = &vec[0];
}
}
template
void doInsert()
{
for(size_t iter=0; iter!=25000 * BASE_FACT; ++iter)
{
Tp vec;
for(std::size_t i=0; i!=1000; ++i)
vec.insert(vec.begin() + vec.size()/2, i);
ptr = &vec[0];
}
}
template
void doInsertInitialized()
{
for(size_t iter=0; iter!=25000 * BASE_FACT; ++iter)
{
Tp vec;
for(std::size_t i=0; i!=100; ++i)
vec.insert(vec.begin() + vec.size()/2, 100, typename Tp::value_type());
ptr = &vec[0];
}
}
template
void doInsertUninitialized()
{
for(size_t iter=0; iter!=25000 * BASE_FACT; ++iter)
{
Tp vec;
for(std::size_t i=0; i!=100; ++i)
vec.insert_uninitialized(vec.begin() + vec.size()/2, 100);
ptr = &vec[0];
}
}
template
void doErase()
{
for(size_t iter=0; iter!=10000 * BASE_FACT; ++iter)
{
Tp vec(1000, 0);
for(std::size_t i=0; i!=1000; ++i)
vec.erase(vec.begin() + vec.size()/2);
ptr = &vec[0];
}
}
template
void doIterate()
{
Tp vec(1000, 1);
for(size_t iter=0; iter!=100000 * BASE_FACT; ++iter)
{
volatile size_t sum = 0;
for(typename Tp::const_iterator i=vec.begin(); i!=vec.end(); ++i)
sum += *i;
}
}
template
void doEquality()
{
Tp vecA(1000, 1), vecB(1000, 1);
for(size_t iter=0; iter!=1000000 * BASE_FACT; ++iter)
{
volatile bool x = (vecA == vecB);
}
}
template
void doSmallerThan()
{
Tp vecA(1000, 1), vecB(1000, 1);
for(size_t iter=0; iter!=100000 * BASE_FACT; ++iter)
{
volatile bool x = (vecA < vecB);
}
}
template
void doSmallerEqualThan()
{
Tp vecA(1000, 1), vecB(1000, 1);
for(size_t iter=0; iter!=100000 * BASE_FACT; ++iter)
{
volatile bool x = (vecA <= vecB);
}
}
template
double test()
{
Stopwatch watch(true);
Func();
return watch.Seconds();
}
struct Measurement
{
const char *name;
double uvecMean, uvecStdDev;
double stdvecMean, stdvecStdDev;
};
template
void measure(struct Measurement& m, const char* name)
{
m.name = name;
const size_t NITERATIONS = 5;
double
uvecTimeSum = 0.0, uvecTimeSumSq = 0.0,
stdvecTimeSum = 0.0, stdvecTimeSumSq = 0.0;
std::cout << "uvector vs std::vector (" << m.name << ")\n";
(std::cout << std::fixed).precision(0);
for(size_t i=0; i!=NITERATIONS; ++i)
{
double
uvecTime = test()*1000.0,
stdvecTime = test()*1000.0;
std::cout << uvecTime << '\t' << stdvecTime << '\n';
uvecTimeSum += uvecTime;
uvecTimeSumSq += uvecTime * uvecTime;
stdvecTimeSum += stdvecTime;
stdvecTimeSumSq += stdvecTime * stdvecTime;
}
m.uvecMean = uvecTimeSum/NITERATIONS,
m.uvecStdDev = sqrt(uvecTimeSumSq / NITERATIONS - m.uvecMean*m.uvecMean),
m.stdvecMean = stdvecTimeSum/NITERATIONS,
m.stdvecStdDev = sqrt(stdvecTimeSumSq / NITERATIONS - m.stdvecMean*m.stdvecMean);
std::cout.precision(2);
std::cout << "Results:\n" << std::fixed <<
" uvector: " << m.uvecMean << " ± " << m.uvecStdDev << " ms\n"
"stdvector: " << m.stdvecMean << " ± " << m.stdvecStdDev << " ms\n";
}
void reportMeasurement(const Measurement& m)
{
std::cout.precision(2);
std::cout << std::fixed
<< m.uvecMean << ",\t" << m.stdvecMean << ",\t"
<< m.uvecMean << " ± " << m.uvecStdDev << ",\t"
<< m.stdvecMean << " ± " << m.stdvecStdDev << ",\t"
<< round((m.uvecMean / m.stdvecMean) * 1000.0)/10.0 << "%,\t"
<< m.name << '\n';
}
int main(int argc, char* argv[])
{
ao::uvector measurements(15);
measure>, doConstruct>>(measurements[0], "constructor");
measure>, doConstructFill>>(measurements[1], "constructor fill");
measure>, doCopyConstruct>>(measurements[2], "copy constructor");
measure>, doAssignCopy>>(measurements[3], "assign copy");
measure>, doAssignMove>>(measurements[4], "assign move");
measure>, doPushback>>(measurements[5], "push_back");
measure>, doPushbackNInitializedImpl>>(measurements[6], "push_back size initialized");
measure>, doPushbackNInitializedImpl>>(measurements[7], "push_back_uninitialized");
measure>, doInsert>>(measurements[8], "insert");
measure>, doInsertInitialized>>(measurements[9], "insert_uninitialized");
measure>, doErase>>(measurements[10], "erase");
measure>, doIterate>>(measurements[11], "iterate");
measure>, doEquality>>(measurements[12], "equality");
measure>, doSmallerThan>>(measurements[13], "smaller than");
measure>, doSmallerEqualThan>>(measurements[14], "smaller or equal than");
for(ao::uvector::const_iterator m=measurements.begin(); m!=measurements.end(); ++m)
reportMeasurement(*m);
std::cout << "\n\nReverse:\n";
for(ao::uvector::const_reverse_iterator m=measurements.rbegin(); m!=measurements.rend(); ++m)
reportMeasurement(*m);
}