#include <iostream>
#include <fstream>
#include <chrono>
#include <vector>
#include <random>
#include <algorithm>
#include <cassert>
using namespace std;
string gen_rand_str(char start_ch,char end_ch,int len)
{
/*Generating random string using Mersene Twister 19937 generator and Uniform discrete distribution.*/
/*start seed with time for randomness*/
std::seed_seq seed{(std::chrono::high_resolution_clock::now().time_since_epoch().count())};
std::mt19937 mt19937_generator{seed};
std::uniform_int_distribution<int> ui_distribution{start_ch,end_ch};
auto generate_len = len;
string rand_str(generate_len,'\0');
for(auto& str: rand_str)
str = ui_distribution(mt19937_generator);
return rand_str;
}
string gen_ascii_data(int rand_size)
{
string rand_data;
char ch_start = '0';
char ch_end = 'z';
rand_data += gen_rand_str(ch_start,ch_end,rand_size) + "\n";
return rand_data;
}
std::vector<uint64_t> gen_bin_data(std::size_t bytes)
{
assert(bytes % sizeof(uint64_t) == 0);
std::vector<uint64_t> data(bytes / sizeof(uint64_t));
std::iota(data.begin(), data.end(), 0);
std::shuffle(data.begin(), data.end(), std::mt19937{ std::random_device{}() });
return data;
}
long long file_stream(string file_name,char* data,std::size_t bytes)
{
auto startTime = std::chrono::high_resolution_clock::now();
auto myfile = std::ofstream(file_name,std::ios::binary);
myfile.write(data, bytes);
myfile.close();
auto endTime = std::chrono::high_resolution_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
}
long long c_style_io(string file_name,char* data,std::size_t bytes)
{
auto startTime = std::chrono::high_resolution_clock::now();
FILE* file = fopen(file_name.c_str(), "wb");
fwrite(data, 1, bytes, file);
fclose(file);
auto endTime = std::chrono::high_resolution_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
}
long long file_stream_no_sync(string file_name,char* data,std::size_t bytes)
{
std::ios_base::sync_with_stdio(false);
auto startTime = std::chrono::high_resolution_clock::now();
auto myfile = std::ofstream(file_name,std::ios::binary);
myfile.write(data, bytes);
myfile.close();
auto endTime = std::chrono::high_resolution_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
}
int main () {
std::ofstream out("ReadWriteLog.txt");
int file_stream_count = 0,c_style_io_count = 0,file_stream_count_no_sync_count = 0;
std::vector<size_t> file_stream_size_vec;
std::vector<size_t> c_style_io_size_vec;
std::vector<size_t> file_stream_count_no_sync_size_vec;
for(uint64_t file_size = sizeof(uint64_t); file_size <= (1ULL << 2); file_size <<= 1){
auto gen_data = gen_bin_data(file_size);
char *buffer = (char*)&gen_data[0];
auto size_mb = file_size / (1024 * 1024);
out << "\nReading file with size : " << size_mb << " MB."<< std::endl;
auto file_stream_time = file_stream("binary.file",buffer,file_size);
auto c_style_io_time = c_style_io("binary.file",buffer,file_size);
auto file_stream_no_sync_time = file_stream_no_sync("binary.file",buffer,file_size);
auto min_time = std::min({file_stream_time,c_style_io_time,file_stream_no_sync_time});
string min_str;
if(min_time == file_stream_time){
min_str = "file_stream";
file_stream_count++;
file_stream_size_vec.push_back(size_mb);
out << "file_stream_time is " << (c_style_io_time - file_stream_time) << " ms ahead of " << "c_style_io_time" << std::endl;
out << "file_stream_time is " << (file_stream_no_sync_time - file_stream_time) << " ms ahead of " << "file_stream_no_sync_time" << std::endl;
}
else if(min_time == c_style_io_time){
min_str = "c_style_io";
c_style_io_count++;
c_style_io_size_vec.push_back(size_mb);
out << "c_style_io_time is " << (file_stream_time - c_style_io_time) << " ms ahead of " << "file_stream_time" << std::endl;
out << "c_style_io_time is " << (file_stream_no_sync_time - c_style_io_time) << " ms ahead of " << "file_stream_no_sync_time" << std::endl;
}
else if(min_time == file_stream_no_sync_time){
min_str = "file_stream_no_sync";
file_stream_count_no_sync_count++;
file_stream_count_no_sync_size_vec.push_back(size_mb);
out << "file_stream_no_sync_time is " << (c_style_io_time - file_stream_no_sync_time) << " ms ahead of " << "c_style_io_time" << std::endl;
out << "file_stream_no_sync_time is " << (file_stream_time - file_stream_no_sync_time) << " ms ahead of " << "file_stream_time" << std::endl;
}
out << "Lesser time of " << min_str << " : " << min_time << " ms"<< std::endl;
}
out << "\nfile_stream count : " << file_stream_count << " files with file size in MB's : " << std::endl;
for(auto& vec : file_stream_size_vec) out << vec << " MB, "; out << std::endl;
out << "\nc_style_io count : " << c_style_io_count << " files with file size in MB's : " << std::endl;
for(auto& vec : c_style_io_size_vec) out << vec << " MB, ";out << std::endl;
out << "\nfile_stream_no_sync count : " << file_stream_count_no_sync_count << " files with file size in MB's : " << std::endl;
for(auto& vec : file_stream_count_no_sync_size_vec) out << vec << " MB, ";out << std::endl;
out.close();
std::cout << "ReadWrite finished writing Logs to file." << std::endl;
return 0;
}