#include<vector>
#include<chrono>
#include<iostream>
#include<memory>
#include<iomanip>

constexpr size_t size = 10'000'000;
constexpr size_t reps = 50;

auto time_vector() {
	auto start = std::chrono::steady_clock::now();
	{
		std::vector<double> a(size);
		for(size_t i = 0; i < size; i++) a[i] = 0;
		std::vector<double> b(size);
		for(size_t i = 0; i < size; i++) b[i] = 0;
		std::vector<double> c(size);
		for(size_t i = 0; i < size; i++) c[i] = 0;

		for (size_t t = 0; t < reps; t++) {
			for (size_t i = 0; i < size; i++) {
				c[i] = a[i] + b[i];
			}
		}
	}
	auto end = std::chrono::steady_clock::now();
	return end - start;
}

auto time_pointer() {
	auto start = std::chrono::steady_clock::now();
	{
		double * a = new double[size];
		for(size_t i = 0; i < size; i++) a[i] = 0;
		double * b = new double[size];
		for(size_t i = 0; i < size; i++) b[i] = 0;
		double * c = new double[size];
		for(size_t i = 0; i < size; i++) c[i] = 0;

		for (size_t t = 0; t < reps; t++) {
			for (size_t i = 0; i < size; i++) {
				c[i] = a[i] + b[i];
			}
		}

		delete[] a;
		delete[] b;
		delete[] c;
	}
	auto end = std::chrono::steady_clock::now();
	return end - start;
}

auto time_unique_ptr() {
	auto start = std::chrono::steady_clock::now();
	{
		std::unique_ptr<double[]> a = std::make_unique<double[]>(size);
		for(size_t i = 0; i < size; i++) a[i] = 0;
		std::unique_ptr<double[]> b = std::make_unique<double[]>(size);
		for(size_t i = 0; i < size; i++) b[i] = 0;
		std::unique_ptr<double[]> c = std::make_unique<double[]>(size);
		for(size_t i = 0; i < size; i++) c[i] = 0;

		for (size_t t = 0; t < reps; t++) {
			for (size_t i = 0; i < size; i++) {
				c[i] = a[i] + b[i];
			}
		}
	}
	auto end = std::chrono::steady_clock::now();
	return end - start;
}

int main() {
	std::cout << "Pointer took        " << std::setw(12) << time_pointer().count() << "ns" << std::endl;
	std::cout << "Vector took         " << std::setw(12) << time_vector().count() << "ns" << std::endl;
	std::cout << "Unique Pointer took " << std::setw(12) << time_unique_ptr().count() << "ns" << std::endl;
	return 0;
}