I wrote this simple program that tests how long it takes for a loop to iterate through a vector<unique_ptr<>>
. I'm wondering if this a good way to perform such a speed test? Are there better methods to this?
Also, I can't seem to use myVector.max_size()
(which is 1073741823) to allocate the maximum amount of entries for a vector. My program crashes even if I go above my current amount of 70 million.
Results:
> Basic took 0ms
> BasicR took 0ms
> Range took 0ms
> Iterator took 0ms
> IteratorR took 36ms
Program:
// main.cpp
#include <iostream>
#include <memory>
#include <vector>
#include <chrono>
#include <iterator>
namespace LoopType {
enum Enum {
Range,
Basic,
BasicR,
Iterator,
IteratorR
};
}
class Test {
public:
explicit Test(const int a) { mA = a; }
int getNum() { return mA; }
private:
int mA;
};
typedef std::vector<std::unique_ptr<Test>> TestVector;
// Loop Types
void RangeBasedForLoop(TestVector& vec) {
for (auto& test : vec) {
int num = test->getNum();
}
}
void BasicLoop(TestVector& vec) {
for (unsigned i = 0; i < vec.size(); ++i) {
int num = vec[i]->getNum();
}
}
void BasicLoopR(TestVector& vec) {
for (unsigned i = vec.size() - 1; i > 0; --i) {
int num = vec[i]->getNum();
}
}
void IteratorLoop(TestVector& vec) {
TestVector::iterator it;
for (it = vec.begin(); it != vec.end(); ++it) {
(*it)->getNum();
}
}
void IteratorLoopR(TestVector& vec) {
TestVector::reverse_iterator it;
for (it = vec.rbegin(); it != vec.rend(); ++it) {
(*it)->getNum();
}
}
// Testing & Printing
long long TestLoop(TestVector& vec, void(*loop)(TestVector&)) {
auto t1 = std::chrono::high_resolution_clock::now();
loop(vec);
auto t2 = std::chrono::high_resolution_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
}
void PrintLoopTime(LoopType::Enum type, TestVector& vec) {
switch (type) {
case LoopType::Basic:
std::cout << "Basic took " << TestLoop(vec, &BasicLoop) << "ms" << std::endl;
break;
case LoopType::BasicR:
std::cout << "BasicR took " << TestLoop(vec, &BasicLoopR) << "ms" << std::endl;
break;
case LoopType::Range:
std::cout << "Range took " << TestLoop(vec, &RangeBasedForLoop) << "ms" << std::endl;
break;
case LoopType::Iterator:
std::cout << "Iterator took " << TestLoop(vec, &IteratorLoop) << "ms" << std::endl;
break;
case LoopType::IteratorR:
std::cout << "IteratorR took " << TestLoop(vec, &IteratorLoopR) << "ms" << std::endl;
break;
}
}
int main() {
const unsigned long seventyMillion = 70000000UL;
std::cout << "Creating vector..." << std::endl;
std::vector<std::unique_ptr<Test>> testVector;
testVector.reserve(seventyMillion);
for (unsigned long i = 0; i < seventyMillion; ++i) {
testVector.emplace_back(std::make_unique<Test>(i));
}
std::cout << testVector.size() << " Elements" << std::endl << std::endl;
std::cout << "Testing loops..." << std::endl << std::endl;
PrintLoopTime(LoopType::Basic, testVector);
PrintLoopTime(LoopType::BasicR, testVector);
PrintLoopTime(LoopType::Range, testVector);
PrintLoopTime(LoopType::Iterator, testVector);
PrintLoopTime(LoopType::IteratorR, testVector);
std::cout << std::endl << "Any key to exit...";
std::cin.get();
return EXIT_SUCCESS;
}