Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //C++ Headers
- #include <iostream>
- #include <fstream>
- #include <vector>
- #include <charconv>
- #include <random>
- #include <chrono>
- //C Headers
- #include <cstdlib>
- #include <cstring>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/mman.h>
- #include <cstdio>
- #include <fcntl.h>
- #include <unistd.h>
- using namespace std;
- using namespace chrono;
- const size_t COUNT = 10000000; //Write 10M ints to disk in ASCII format
- void die(string s) {
- cerr << s << endl;
- exit(EXIT_FAILURE);
- }
- int main() {
- //Generate some random numbers
- auto start = steady_clock::now();
- using data_type = uint32_t;
- vector<data_type> vec;
- vec.reserve(COUNT);
- default_random_engine gen;
- uniform_int_distribution<data_type> rando;
- for (size_t i = 0; i < COUNT; i++) vec.push_back(rando(gen)); //Emplace_back doesn't change the time
- duration <double, milli> dur = steady_clock::now() - start;
- cout << "Random vector generation time: " << dur.count() << "ms\n";
- //Create a buffer with all the data converted into it to minimize write calls
- start = steady_clock::now();
- const size_t DIGITS = 11; //10 digits + newline needed for each int, max
- const size_t SIZE = COUNT * DIGITS; //Bytes in the array
- char *buffer = new char[SIZE];
- char *ptr = buffer; //Pointer to where we're writing to the array
- char *end = buffer + sizeof(char) * SIZE; //Pointer to one past the end of the array
- for (auto i : vec) {
- ptr = to_chars(ptr,end,i).ptr; //We're ignoring the error condition, which should be fine
- *ptr++ = '\n'; //Write a newline at the end and advance the pointer one char
- }
- duration <double, milli> buf_dur = steady_clock::now() - start;
- cout << "Buffer conversion time: " << buf_dur.count() << "ms\n";
- //Benchmark fprintf
- start = steady_clock::now();
- FILE *file1 = fopen("fprintf.txt", "w");
- for (auto i : vec) fprintf(file1, "%u\n", i);
- fclose(file1);
- dur = steady_clock::now() - start;
- cout << "Fprintf time: " << dur.count() << "ms\n";
- //Benchmark fstream
- ofstream file2("fstream.txt");
- start = steady_clock::now();
- //for (auto i : vec) file2 << i << endl; //Don't do this, it is 10-20x slower
- for (auto i : vec) file2 << i << '\n';
- file2.close();
- dur = steady_clock::now() - start;
- cout << "Fstream time: " << dur.count() << "ms\n";
- //Benchmark syscall write time
- start = steady_clock::now();
- int file3 = creat("fsyscall.txt", S_IRWXU); //syscall to open a file, returns a file descriptor (int)
- size_t bytes_written = static_cast<size_t>(ptr-buffer);
- size_t result = write(file3, buffer, bytes_written);
- if (!result) die("We need this since the header files don't like you discarding the result\n");
- close(file3); //syscall to close a file
- dur = steady_clock::now() - start;
- cout << "Syscall write time (with buffer): " << dur.count() + buf_dur.count() << "ms\n";
- //Benchmark fprintf with a buffer
- start = steady_clock::now();
- FILE *file4 = fopen("fprintf2.txt", "w");
- fprintf(file4, "%s", buffer);
- fclose(file4);
- dur = steady_clock::now() - start;
- cout << "Fprintf time (with buffer): " << dur.count() + buf_dur.count() << "ms\n";
- //Benchmark fstream with a buffer
- start = steady_clock::now();
- ofstream file5("fstream2.txt");
- file5 << buffer;
- file5.close();
- dur = steady_clock::now() - start;
- cout << "Fstream time (with buffer): " << dur.count() + buf_dur.count() << "ms\n";
- //Benchmark mmap files with a buffer
- start = steady_clock::now();
- int file6 = open ("fsyscall2.txt", O_RDWR | O_CREAT | O_TRUNC, 0x0777);
- if (file6 == -1) die("Open file6 failed\n");
- auto retval = lseek(file6,bytes_written-1,SEEK_SET); //Make a 0 byte file...
- if (retval == -1) die("Lseek failed\n");
- retval = write(file6, "", 1); //...really big by writing to what will be the end
- if (retval != 1) die("Write failed\n");
- char *file_array = (char *)mmap (0, bytes_written, PROT_READ | PROT_WRITE, MAP_SHARED, file6, 0); //Treat file as array
- if (file_array == MAP_FAILED) die("Mmap error");
- memcpy (file_array, buffer, bytes_written); //Copy files to disk
- munmap(file_array,bytes_written); //Unmap file
- close(file6);
- dur = steady_clock::now() - start;
- cout << "Mmap time (with buffer): " << dur.count() + buf_dur.count() << "ms\n";
- delete[] buffer;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement