#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); }