LCOV - code coverage report
Current view: top level - core - timer.h (source / functions) Coverage Total Hit
Test: hashbrowns Coverage Lines: 100.0 % 28 28
Test Date: 2026-04-10 19:00:18 Functions: 100.0 % 12 12
Legend: Lines: hit not hit

            Line data    Source code
       1              : #ifndef HASHBROWNS_TIMER_H
       2              : #define HASHBROWNS_TIMER_H
       3              : 
       4              : #include <chrono>
       5              : #include <vector>
       6              : #include <string>
       7              : #include <algorithm>
       8              : #include <numeric>
       9              : #include <cmath>
      10              : #include <functional>
      11              : #include <thread>
      12              : 
      13              : namespace hashbrowns {
      14              : 
      15              : /**
      16              :  * @brief High-precision timer for benchmarking operations
      17              :  * 
      18              :  * This class provides microsecond-precision timing with statistical analysis
      19              :  * capabilities. It's designed to handle the challenges of accurate performance
      20              :  * measurement including warm-up periods, outlier detection, and statistical
      21              :  * aggregation across multiple runs.
      22              :  */
      23              : class Timer {
      24              : public:
      25              :     using clock_type = std::chrono::high_resolution_clock;
      26              :     using time_point = clock_type::time_point;
      27              :     using duration = std::chrono::nanoseconds;
      28              : 
      29              :     /**
      30              :      * @brief Statistical summary of timing measurements
      31              :      */
      32              :     struct Statistics {
      33              :         double mean_ns;         ///< Mean time in nanoseconds
      34              :         double median_ns;       ///< Median time in nanoseconds
      35              :         double std_dev_ns;      ///< Standard deviation in nanoseconds
      36              :         double min_ns;          ///< Minimum time in nanoseconds
      37              :         double max_ns;          ///< Maximum time in nanoseconds
      38              :         size_t sample_count;    ///< Number of samples
      39              :         double outlier_ratio;   ///< Ratio of outliers removed
      40              : 
      41              :         // Convenience accessors for different time units
      42              :         double mean_us() const { return mean_ns / 1000.0; }
      43            2 :         double mean_ms() const { return mean_ns / 1000000.0; }
      44              :         double median_us() const { return median_ns / 1000.0; }
      45            2 :         double median_ms() const { return median_ns / 1000000.0; }
      46              :         double std_dev_us() const { return std_dev_ns / 1000.0; }
      47            2 :         double std_dev_ms() const { return std_dev_ns / 1000000.0; }
      48              :     };
      49              : 
      50              :     /**
      51              :      * @brief Construct timer with optional outlier detection
      52              :      * @param remove_outliers If true, automatically remove statistical outliers
      53              :      * @param outlier_threshold Z-score threshold for outlier detection (default 2.0)
      54              :      */
      55              :     explicit Timer(bool remove_outliers = true, double outlier_threshold = 2.0);
      56              : 
      57              :     /**
      58              :      * @brief Start timing an operation
      59              :      */
      60              :     void start();
      61              : 
      62              :     /**
      63              :      * @brief Stop timing and record the duration
      64              :      * @return Duration of the timed operation in nanoseconds
      65              :      */
      66              :     duration stop();
      67              : 
      68              :     /**
      69              :      * @brief Add a pre-measured duration to the sample set
      70              :      * @param d Duration to add
      71              :      */
      72              :     void add_sample(duration d);
      73              : 
      74              :     /**
      75              :      * @brief Get the duration of the last measured operation
      76              :      * @return Last measured duration in nanoseconds
      77              :      */
      78            1 :     duration last_duration() const { return last_duration_; }
      79              : 
      80              :     /**
      81              :      * @brief Clear all recorded samples
      82              :      */
      83              :     void reset();
      84              : 
      85              :     /**
      86              :      * @brief Get statistical summary of all recorded samples
      87              :      * @return Statistics object with aggregated timing data
      88              :      */
      89              :     Statistics get_statistics() const;
      90              : 
      91              :     /**
      92              :      * @brief Get all raw sample durations
      93              :      * @return Vector of all recorded durations
      94              :      */
      95              :     const std::vector<duration>& get_samples() const { return samples_; }
      96              : 
      97              :     /**
      98              :      * @brief Get number of recorded samples
      99              :      */
     100            2 :     size_t sample_count() const { return samples_.size(); }
     101              : 
     102              :     /**
     103              :      * @brief Check if timer is currently running
     104              :      */
     105            1 :     bool is_running() const { return is_running_; }
     106              : 
     107              :     /**
     108              :      * @brief Perform warm-up runs to stabilize CPU caches and frequency
     109              :      * @param warmup_count Number of warm-up iterations
     110              :      * @param operation Function to execute during warm-up
     111              :      */
     112              :     template<typename Func>
     113            2 :     void warmup(size_t warmup_count, Func&& operation) {
     114           12 :         for (size_t i = 0; i < warmup_count; ++i) {
     115           10 :             operation();
     116              :         }
     117              :         // Give CPU time to settle after warm-up
     118            2 :         std::this_thread::sleep_for(std::chrono::milliseconds(1));
     119            2 :     }
     120              : 
     121              :     /**
     122              :      * @brief Time a function multiple times and collect statistics
     123              :      * @param operation Function to time
     124              :      * @param iterations Number of iterations to run
     125              :      * @param warmup_runs Number of warm-up runs before timing
     126              :      * @return Statistics for the timed operations
     127              :      */
     128              :     template<typename Func>
     129            2 :     Statistics time_operation(Func&& operation, size_t iterations, size_t warmup_runs = 3) {
     130            2 :         reset();
     131              :         
     132              :         // Warm-up phase
     133            2 :         if (warmup_runs > 0) {
     134            2 :             warmup(warmup_runs, operation);
     135              :         }
     136              :         
     137              :         // Actual timing
     138           22 :         for (size_t i = 0; i < iterations; ++i) {
     139           20 :             start();
     140           20 :             operation();
     141           20 :             stop();
     142              :         }
     143              :         
     144            2 :         return get_statistics();
     145              :     }
     146              : 
     147              : private:
     148              :     time_point start_time_;
     149              :     duration last_duration_;
     150              :     std::vector<duration> samples_;
     151              :     bool is_running_;
     152              :     bool remove_outliers_;
     153              :     double outlier_threshold_;
     154              : 
     155              :     /**
     156              :      * @brief Remove statistical outliers from samples
     157              :      * @param data Vector of durations to filter
     158              :      * @return Filtered vector with outliers removed
     159              :      */
     160              :     std::vector<duration> remove_outliers(const std::vector<duration>& data) const;
     161              : 
     162              :     /**
     163              :      * @brief Calculate Z-score for a value in a dataset
     164              :      */
     165              :     double calculate_zscore(double value, double mean, double std_dev) const;
     166              : };
     167              : 
     168              : /**
     169              :  * @brief RAII scope timer for automatic timing of code blocks
     170              :  * 
     171              :  * This class automatically starts timing on construction and stops on destruction,
     172              :  * making it perfect for timing scoped operations.
     173              :  * 
     174              :  * Example usage:
     175              :  * @code
     176              :  * {
     177              :  *     ScopeTimer timer("Operation Name");
     178              :  *     // ... code to time ...
     179              :  * } // timer automatically stops and optionally prints result
     180              :  * @endcode
     181              :  */
     182              : class ScopeTimer {
     183              : public:
     184              :     /**
     185              :      * @brief Construct scope timer with optional name and auto-print
     186              :      * @param name Optional name for the operation being timed
     187              :      * @param auto_print If true, print timing result on destruction
     188              :      */
     189              :     explicit ScopeTimer(const std::string& name = "", bool auto_print = true);
     190              : 
     191              :     /**
     192              :      * @brief Destructor - automatically stops timing
     193              :      */
     194              :     ~ScopeTimer();
     195              : 
     196              :     /**
     197              :      * @brief Get the elapsed time so far (without stopping)
     198              :      * @return Current elapsed time
     199              :      */
     200              :     Timer::duration elapsed() const;
     201              : 
     202              :     /**
     203              :      * @brief Manually stop the timer and get final duration
     204              :      * @return Total elapsed time
     205              :      */
     206              :     Timer::duration stop();
     207              : 
     208              : private:
     209              :     Timer::time_point start_time_;
     210              :     std::string operation_name_;
     211              :     bool auto_print_;
     212              :     bool stopped_;
     213              : };
     214              : 
     215              : /**
     216              :  * @brief Benchmark runner for comparative performance analysis
     217              :  * 
     218              :  * This class facilitates running multiple benchmark tests and comparing
     219              :  * their performance characteristics.
     220              :  */
     221              : class BenchmarkRunner {
     222              : public:
     223              :     struct BenchmarkResult {
     224              :         std::string name;
     225              :         Timer::Statistics stats;
     226              :         double operations_per_second;
     227              :         size_t data_size;
     228              :     };
     229              : 
     230              :     /**
     231              :      * @brief Add a benchmark test
     232              :      * @param name Name identifier for the benchmark
     233              :      * @param operation Function to benchmark
     234              :      * @param iterations Number of times to run the operation
     235              :      * @param data_size Size of data being processed (for throughput calculation)
     236              :      */
     237              :     template<typename Func>
     238            2 :     void add_benchmark(const std::string& name, Func&& operation, 
     239              :                       size_t iterations, size_t data_size = 0) {
     240            2 :         Timer timer(true, 2.0); // Remove outliers with 2-sigma threshold
     241            2 :         auto stats = timer.time_operation(std::forward<Func>(operation), iterations, 5);
     242              :         
     243            2 :         double ops_per_sec = 0.0;
     244            2 :         if (stats.mean_ns > 0) {
     245            2 :             ops_per_sec = 1e9 / stats.mean_ns; // Convert to operations per second
     246              :         }
     247              :         
     248            4 :         results_.push_back({name, stats, ops_per_sec, data_size});
     249            6 :     }
     250              : 
     251              :     /**
     252              :      * @brief Get all benchmark results
     253              :      */
     254              :     const std::vector<BenchmarkResult>& get_results() const { return results_; }
     255              : 
     256              :     /**
     257              :      * @brief Clear all results
     258              :      */
     259              :     void clear() { results_.clear(); }
     260              : 
     261              :     /**
     262              :      * @brief Print formatted benchmark comparison
     263              :      */
     264              :     void print_comparison() const;
     265              : 
     266              :     /**
     267              :      * @brief Export results to CSV format
     268              :      * @param filename Output CSV file path
     269              :      */
     270              :     void export_csv(const std::string& filename) const;
     271              : 
     272              : private:
     273              :     std::vector<BenchmarkResult> results_;
     274              : };
     275              : 
     276              : /**
     277              :  * @brief Convenience macro for scope timing
     278              :  */
     279              : #define SCOPE_TIMER(name) hashbrowns::ScopeTimer _scope_timer(name)
     280              : 
     281              : /**
     282              :  * @brief Convenience macro for scope timing with custom auto-print setting
     283              :  */
     284              : #define SCOPE_TIMER_PRINT(name, print) hashbrowns::ScopeTimer _scope_timer(name, print)
     285              : 
     286              : } // namespace hashbrowns
     287              : 
     288              : #endif // HASHBROWNS_TIMER_H
        

Generated by: LCOV version 2.0-1