fork download
  1.  
  2. #pragma once
  3.  
  4. #include <chrono>
  5. #include <type_traits>
  6.  
  7. template <typename Clock>
  8. class stopwatch
  9. {
  10. public:
  11. typedef Clock clock;
  12. typedef typename clock::time_point time_point;
  13. typedef typename clock::duration duration;
  14.  
  15. private:
  16. time_point last_;
  17.  
  18. public:
  19. stopwatch()
  20. : last_(clock::now())
  21. {}
  22.  
  23. void reset()
  24. {
  25. *this = stopwatch();
  26. }
  27.  
  28. time_point now() const
  29. {
  30. return clock::now();
  31. }
  32.  
  33. duration elapsed() const
  34. {
  35. return now() - last_;
  36. }
  37.  
  38. duration tick()
  39. {
  40. time_point dummy;
  41. return tick(dummy);
  42. }
  43.  
  44. duration tick(time_point& now_)
  45. {
  46. now_ = now();
  47. auto elapsed = now_ - last_;
  48. last_ = now_;
  49. return elapsed;
  50. }
  51. };
  52.  
  53. typedef stopwatch<std::chrono::steady_clock> default_stopwatch;
  54.  
  55. template <typename T, typename Rep, typename Period,
  56. typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
  57. T float_cast(const std::chrono::duration<Rep, Period>& duration, T mul = T(1))
  58. {
  59. return duration.count() * mul * (T(Period::num) / T(Period::den));
  60. }
  61.  
  62.  
  63. #include <cstring>
  64. #include <algorithm>
  65. #include <array>
  66. #include <functional>
  67. #include <iostream>
  68. #include <random>
  69.  
  70. template <typename RNG>
  71. RNG make_rng()
  72. {
  73. std::random_device rd;
  74. std::array<typename RNG::result_type, RNG::state_size> seed_data;
  75. std::generate(seed_data.begin(), seed_data.end(), std::ref(rd));
  76. std::seed_seq seq(seed_data.begin(), seed_data.end());
  77. return RNG(seq);
  78. }
  79.  
  80. template <typename RNG>
  81. void test_rng(RNG& rng, void* buffer, std::size_t size)
  82. {
  83. while (size >= sizeof(decltype(rng())))
  84. {
  85. auto r = rng();
  86. std::memcpy(buffer, &r, sizeof r);
  87. buffer = static_cast<char*>(buffer) + sizeof r;
  88. size -= sizeof r;
  89. }
  90. }
  91.  
  92. int main()
  93. {
  94. const std::size_t mb = 512;
  95. std::vector<char> buf(mb * 1024 * 1024);
  96. default_stopwatch sw;
  97. double t;
  98. auto rng1 = make_rng<std::mt19937>();
  99. auto rng2 = make_rng<std::mt19937_64>();
  100. auto rng3 = std::minstd_rand((std::random_device()()));
  101.  
  102. sw.reset();
  103. test_rng(rng1, buf.data(), buf.size());
  104. t = float_cast<double>(sw.elapsed());
  105. std::cout << "mt19937: " << t << " - " << mb / t << " MB/s\n";
  106.  
  107. sw.reset();
  108. test_rng(rng2, buf.data(), buf.size());
  109. t = float_cast<double>(sw.elapsed());
  110. std::cout << "mt19937_64: " << t << " - " << mb / t << " MB/s\n";
  111.  
  112. sw.reset();
  113. test_rng(rng3, buf.data(), buf.size());
  114. t = float_cast<double>(sw.elapsed());
  115. std::cout << "minstd_rand: " << t << " - " << mb / t << " MB/s\n";
  116. }
Success #stdin #stdout 4.38s 3276KB
stdin
Standard input is empty
stdout
mt19937: 1.43599 - 356.548 MB/s
mt19937_64: 1.50422 - 340.377 MB/s
minstd_rand: 0.858734 - 596.227 MB/s