#include <iostream>
#include <vector>
#include <chrono>
#include <algorithm>

template <typename timepoint_type>
void display_time_difference(timepoint_type start, timepoint_type end)
{
    using namespace std::chrono;

    std::cout << "Took " << duration_cast<milliseconds>(end - start).count() ;
    std::cout << " ms." << std::endl;
}

int main()
{
    const unsigned outer_size = 10000;
    const unsigned inner_size = 5000;


    std::cout << "1) a 2D dynamic array of size " << outer_size ;
    std::cout << " x " << inner_size << std::endl;

    auto start = std::chrono::high_resolution_clock::now();

    int** array2D = new int*[outer_size];
    for (unsigned i = 0; i < outer_size; i++) 
    {
        array2D[i] = new int[inner_size];
        std::fill(array2D[i], array2D[i] + inner_size, 1);
    }

    auto end = std::chrono::high_resolution_clock::now();
    display_time_difference(start, end);

    for (unsigned i = 0; i < outer_size; ++i)
        delete [] array2D[outer_size-i-1];
    delete [] array2D;
  

    std::cout << "2) a 2D vector of size " << outer_size;
    std::cout << " x " << inner_size << ", using resize" << std::endl;
    start = std::chrono::high_resolution_clock::now();
    {
        std::vector<std::vector<int> > vec2D;
        vec2D.resize(outer_size);
        for (unsigned i = 0; i < outer_size; i++)
        {
            vec2D[i].resize(inner_size);
            std::fill(vec2D[i].begin(), vec2D[i].end(), 1);
        }

        end = std::chrono::high_resolution_clock::now();
    }
    display_time_difference(start, end);


    std::cout << "3) a 2D vector of size " << outer_size;
    std::cout << " x " << inner_size << ", using push_back" << std::endl;
    start = std::chrono::high_resolution_clock::now();
    {
        std::vector<std::vector<int> > vec2D;
        for (unsigned i = 0; i < outer_size; ++i)
        {
            vec2D.push_back(std::vector<int>());
            std::vector<int>& v = vec2D.back();
            for (unsigned j = 0; j < inner_size; ++j)
                v.push_back(1);
        }
        end = std::chrono::high_resolution_clock::now();
    }
    display_time_difference(start, end);


    std::cout << "4) a 2D vector of size " << outer_size;
    std::cout << " x " << inner_size << ", using constructors" << std::endl;
    start = std::chrono::high_resolution_clock::now();
    {
        std::vector<std::vector<int>> vec2D(outer_size, std::vector<int>(inner_size, 1));
        end = std::chrono::high_resolution_clock::now();
    }
    display_time_difference(start, end);
}