Advertisement
Guest User

io benchmarking for C++

a guest
Aug 14th, 2019
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.20 KB | None | 0 0
  1. //C++ Headers
  2. #include <iostream>
  3. #include <fstream>
  4. #include <vector>
  5. #include <charconv>
  6. #include <random>
  7. #include <chrono>
  8.  
  9. //C Headers
  10. #include <cstdlib>
  11. #include <cstring>
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include <sys/mman.h>
  15. #include <cstdio>
  16. #include <fcntl.h>
  17. #include <unistd.h>
  18. using namespace std;
  19. using namespace chrono;
  20.  
  21. const size_t COUNT = 10000000; //Write 10M ints to disk in ASCII format
  22.  
  23. void die(string s) {
  24.     cerr << s << endl;
  25.     exit(EXIT_FAILURE);
  26. }
  27.  
  28. int main() {
  29.     //Generate some random numbers
  30.     auto start = steady_clock::now();
  31.     using data_type = uint32_t;
  32.     vector<data_type> vec;
  33.     vec.reserve(COUNT);
  34.     default_random_engine gen;
  35.     uniform_int_distribution<data_type> rando;
  36.     for (size_t i = 0; i < COUNT; i++) vec.push_back(rando(gen)); //Emplace_back doesn't change the time
  37.     duration <double, milli> dur = steady_clock::now() - start;
  38.     cout << "Random vector generation time: " << dur.count() << "ms\n";
  39.  
  40.     //Create a buffer with all the data converted into it to minimize write calls
  41.     start = steady_clock::now();
  42.     const size_t DIGITS = 11; //10 digits + newline needed for each int, max
  43.     const size_t SIZE = COUNT * DIGITS; //Bytes in the array
  44.     char *buffer = new char[SIZE];
  45.     char *ptr = buffer; //Pointer to where we're writing to the array
  46.     char *end = buffer + sizeof(char) * SIZE; //Pointer to one past the end of the array
  47.     for (auto i : vec) {
  48.         ptr = to_chars(ptr,end,i).ptr; //We're ignoring the error condition, which should be fine
  49.         *ptr++ = '\n'; //Write a newline at the end and advance the pointer one char
  50.     }
  51.     duration <double, milli> buf_dur = steady_clock::now() - start;
  52.     cout << "Buffer conversion time: " << buf_dur.count() << "ms\n";
  53.  
  54.     //Benchmark fprintf
  55.     start = steady_clock::now();
  56.     FILE *file1 = fopen("fprintf.txt", "w");
  57.     for (auto i : vec) fprintf(file1, "%u\n", i);
  58.     fclose(file1);
  59.     dur = steady_clock::now() - start;
  60.     cout << "Fprintf time: " << dur.count() << "ms\n";
  61.  
  62.     //Benchmark fstream
  63.     ofstream file2("fstream.txt");
  64.     start = steady_clock::now();
  65.     //for (auto i : vec) file2 << i << endl; //Don't do this, it is 10-20x slower
  66.     for (auto i : vec) file2 << i << '\n';
  67.     file2.close();
  68.     dur = steady_clock::now() - start;
  69.     cout << "Fstream time: " << dur.count() << "ms\n";
  70.  
  71.     //Benchmark syscall write time
  72.     start = steady_clock::now();
  73.     int file3 = creat("fsyscall.txt", S_IRWXU); //syscall to open a file, returns a file descriptor (int)
  74.     size_t bytes_written = static_cast<size_t>(ptr-buffer);
  75.     size_t result = write(file3, buffer, bytes_written);
  76.     if (!result) die("We need this since the header files don't like you discarding the result\n");
  77.     close(file3); //syscall to close a file
  78.     dur = steady_clock::now() - start;
  79.     cout << "Syscall write time (with buffer): " << dur.count() + buf_dur.count() << "ms\n";
  80.  
  81.     //Benchmark fprintf with a buffer
  82.     start = steady_clock::now();
  83.     FILE *file4 = fopen("fprintf2.txt", "w");
  84.     fprintf(file4, "%s", buffer);
  85.     fclose(file4);
  86.     dur = steady_clock::now() - start;
  87.     cout << "Fprintf time (with buffer): " << dur.count() + buf_dur.count() << "ms\n";
  88.  
  89.     //Benchmark fstream with a buffer
  90.     start = steady_clock::now();
  91.     ofstream file5("fstream2.txt");
  92.     file5 << buffer;
  93.     file5.close();
  94.     dur = steady_clock::now() - start;
  95.     cout << "Fstream time (with buffer): " << dur.count() + buf_dur.count() << "ms\n";
  96.  
  97.     //Benchmark mmap files with a buffer
  98.     start = steady_clock::now();
  99.     int file6 = open ("fsyscall2.txt", O_RDWR | O_CREAT | O_TRUNC, 0x0777);
  100.     if (file6 == -1) die("Open file6 failed\n");
  101.     auto retval = lseek(file6,bytes_written-1,SEEK_SET); //Make a 0 byte file...
  102.     if (retval == -1) die("Lseek failed\n");
  103.     retval = write(file6, "", 1); //...really big by writing to what will be the end
  104.     if (retval != 1) die("Write failed\n");
  105.     char *file_array = (char *)mmap (0, bytes_written, PROT_READ | PROT_WRITE, MAP_SHARED, file6, 0); //Treat file as array
  106.     if (file_array == MAP_FAILED) die("Mmap error");
  107.     memcpy (file_array, buffer, bytes_written); //Copy files to disk
  108.     munmap(file_array,bytes_written); //Unmap file
  109.     close(file6);
  110.     dur = steady_clock::now() - start;
  111.     cout << "Mmap time (with buffer): " << dur.count() + buf_dur.count() << "ms\n";
  112.  
  113.     delete[] buffer;
  114. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement