
#include <iostream>
#include <chrono>
#include <vector>
#include <array>


//Force 1-byte alignment
#pragma pack(push, 1)
struct UnalignedData {
	char c;
	double d;
	int i;
};
#pragma pack(pop)


//aligned and padded by compiler
struct AlignedData {
	double d;
	int i;
	char c;
};


void performance_test(){
	const int iterations = static_cast<int>(1e4);
	std::vector<UnalignedData> unaligned(iterations) ;
	std::vector<AlignedData> aligned(iterations);
    std::array<double, iterations> collect;

    //initial
    for(int i = 0; i < iterations; ++i){
        unaligned[i] = {static_cast<char>(i), i * 3.14, i};
        aligned[i] = {i * 3.14, i, static_cast<char>(i)};
    }

	//unaligned
	auto start = std::chrono::high_resolution_clock::now();
	
	for(int i = 0; i < iterations; ++i){
		collect[i] = unaligned[i].d;
	}
	
	auto end = std::chrono::high_resolution_clock::now();
	std::chrono::duration<double, std::milli> unaligned_time(end - start);
	
	
	//aligned
	start = std::chrono::high_resolution_clock::now();
	for(int i = 0; i < iterations; ++i){
		collect[i] = aligned[i].d;
	}
	end = std::chrono::high_resolution_clock::now();
	std::chrono::duration<double, std::milli> aligned_time(end - start);
	
	
	std::cout << "Exec Time of Unaligned: " << unaligned_time.count() << "ms" << std::endl;
	std::cout << "Exec Time of Aligned: " << aligned_time.count() << "ms" << std::endl;
	std::cout << "Performance Improvement: " << (unaligned_time.count() / aligned_time.count() -1)*100 << "%" << std::endl;
	
	
}


int main(){
	
	performance_test();
	return 0;
}
