Advertisement
Guest User

Untitled

a guest
Nov 13th, 2018
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.41 KB | None | 0 0
  1. #pragma once
  2.  
  3. #ifdef __linux__
  4. #include <time.h>
  5. #elif _WIN32
  6. #include <Windows.h>
  7. #endif
  8.  
  9. #include <iostream>
  10. #include <functional>
  11. #include <optional>
  12.  
  13. template<typename U, typename T, typename ... Args>
  14. class Timer{
  15.  
  16. public:
  17.     Timer() = delete;
  18.    
  19.     Timer(T(U::*fnc_to_measure)( Args ... args), U* context)
  20.         : fnc_to_measure_{ fnc_to_measure }, context_{ context }
  21.     {};
  22.  
  23.     ~Timer() = default;
  24.     Timer& operator=(const Timer& rhs) = default;
  25.  
  26.     double run(Args ... args);
  27.     double run_average(const int executions);
  28.  
  29.     T get_output();
  30.  
  31. private:
  32.  
  33.     U* context_;
  34.     T (U::*fnc_to_measure_)(Args ... args);
  35.     std::optional<T> alg_value;
  36.  
  37.     void start_counter();
  38.     double get_time();
  39.  
  40.     // Attributes for OS specific timing functions.
  41.     #ifdef __linux__
  42.     clock_t start_time_;
  43.  
  44.     #elif _WIN32
  45.     double pc_freq_ = 0.0;
  46.     long long start_time_;
  47.    
  48.     #endif
  49. };
  50.  
  51. template<typename U, typename T, typename ... Args>
  52. double Timer<U, T, Args ... >::run(Args ... args)
  53. {
  54.     start_counter();
  55.     alg_value = (context_->*fnc_to_measure_)(args ...);
  56.     return get_time();
  57. }
  58.  
  59. template<typename U, typename T, typename ... Args>
  60. double Timer<U, T, Args ...>::run_average(const int executions)
  61. {
  62.     double accu_time{ 0 };
  63.  
  64.     for (int i{ 0 }; i < executions; ++i)
  65.         accu_time += run();
  66.  
  67.     return accu_time / executions;
  68. }
  69.  
  70. #ifdef __linux__
  71.  
  72. template<typename T, typename ... Args>
  73. void Timer<T, Args ...>::start_counter()
  74. {
  75.     start_time_ = clock();
  76. }
  77.  
  78. template<typename T, typename ... Args>
  79. double Timer<T, Args ...>::get_time()
  80. {
  81.     return (clock() - start_time_) / static_cast<double>(CLOCKS_PER_SEC) ;  // Time in seconds.
  82. }
  83.  
  84. #elif _WIN32
  85. template<typename U, typename T, typename ... Args>
  86. void Timer<U, T, Args ...>::start_counter()
  87. {
  88.     LARGE_INTEGER per_f;
  89.     if (QueryPerformanceFrequency(&per_f))
  90.  
  91.         pc_freq_ = double(per_f.QuadPart) / 1000.0;
  92.  
  93.     QueryPerformanceCounter(&per_f);
  94.     start_time_ = per_f.QuadPart;
  95. }
  96.  
  97. template<typename U, typename T, typename ... Args>
  98. double Timer<U, T, Args ...>::get_time()
  99. {
  100.     LARGE_INTEGER per_f;
  101.     QueryPerformanceCounter(&per_f);
  102.     return double(per_f.QuadPart - start_time_) / pc_freq_;
  103. }
  104. #endif
  105.  
  106. template<typename U, typename T, typename ... Args>
  107. T Timer<U, T, Args ...>::get_output()
  108. {
  109.     if(alg_value.has_value())
  110.         return alg_value.value();
  111.     else
  112.         throw std::invalid_argument("Timed function does not return a value.");
  113. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement