Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-15 09:22:41

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Utilities/Logger.hpp"
0012 
0013 #include <atomic>
0014 #include <chrono>
0015 #include <cstddef>
0016 
0017 namespace Acts {
0018 
0019 /// @brief A RAII timer class for measuring execution time of code blocks
0020 ///
0021 /// ScopedTimer provides automatic timing of code blocks using RAII principles.
0022 /// It starts timing when constructed and automatically logs the duration when
0023 /// destroyed. This makes it ideal for measuring execution time of functions
0024 /// or code blocks without manual start/stop calls.
0025 ///
0026 /// Example usage:
0027 /// @code
0028 /// {
0029 ///   ScopedTimer timer("myFunction");
0030 ///   // ... code to measure ...
0031 /// } // Timer automatically logs duration when block ends
0032 /// @endcode
0033 ///
0034 class ScopedTimer {
0035  public:
0036   /// Type alias for high resolution clock used for timing
0037   using clock_type = std::chrono::high_resolution_clock;
0038 
0039   /// @brief Construct a new Scoped Timer
0040   ///
0041   /// @param name Identifier for the timed block
0042   /// @param logger Logger instance to use for output
0043   /// @param lvl Logging level for the timing output
0044   explicit ScopedTimer(const std::string& name, const Logger& logger,
0045                        Logging::Level lvl = Logging::Level::INFO);
0046 
0047   /// @brief Destructor that logs the execution time
0048   ///
0049   /// Automatically calculates and logs the duration between construction
0050   /// and destruction using the specified logger and level.
0051   /// Exceptions from formatting or logging terminate the process.
0052   ~ScopedTimer() noexcept;
0053 
0054   ScopedTimer(const ScopedTimer&) = delete;
0055   ScopedTimer& operator=(const ScopedTimer&) = delete;
0056   ScopedTimer(ScopedTimer&&) = delete;
0057   ScopedTimer& operator=(ScopedTimer&&) = delete;
0058 
0059  private:
0060   std::string m_name;      ///< Identifier for the timed block
0061   Logging::Level m_lvl;    ///< Logging level for output
0062   const Logger* m_logger;  ///< Logger instance for output
0063   clock_type::time_point m_start =
0064       clock_type::now();  ///< Start time of the timer
0065 };
0066 
0067 /// @brief A timer class that measures and averages execution times of multiple samples
0068 ///
0069 /// This class provides functionality to measure execution times of code blocks
0070 /// and calculate statistics (mean, standard deviation) across multiple samples.
0071 /// It uses RAII through the Sample class to automatically record timing
0072 /// information.
0073 ///
0074 /// All samples must be destroyed before this timer. When recording samples on
0075 /// other threads, synchronize their completion (for example, by joining the
0076 /// threads) before destroying the timer.
0077 class AveragingScopedTimer {
0078  public:
0079   /// Type alias for high resolution clock used for timing measurements
0080   using clock_type = std::chrono::high_resolution_clock;
0081 
0082   /// @brief RAII wrapper class for measuring individual timing samples
0083   ///
0084   /// When constructed, starts a timer. When destroyed, automatically records
0085   /// the duration to the parent AveragingScopedTimer.
0086   class Sample {
0087    public:
0088     /// @brief Construct a new sample and start timing
0089     /// @param parent The parent averaging scoped timer to record to
0090     explicit Sample(AveragingScopedTimer& parent);
0091     /// @brief Record the duration when destroyed
0092     ~Sample();
0093     Sample(const Sample&) = delete;
0094     Sample& operator=(const Sample&) = delete;
0095     /// @brief Move constructor that transfers ownership of timing to new sample
0096     Sample(Sample&& /*other*/) noexcept;
0097     Sample& operator=(Sample&&) = delete;
0098 
0099    private:
0100     AveragingScopedTimer* m_parent;
0101     clock_type::time_point m_start = clock_type::now();
0102   };
0103 
0104   /// @brief Construct a new AveragingScopedTimer
0105   ///
0106   /// @param name Name of the timer for logging
0107   /// @param logger Logger instance to use for output
0108   /// @param lvl Logging level for timing output
0109   explicit AveragingScopedTimer(const std::string& name, const Logger& logger,
0110                                 Logging::Level lvl = Logging::Level::INFO);
0111 
0112   /// @brief Destroy the AveragingScopedTimer and log statistics
0113   ///
0114   /// Outputs total duration and per-sample statistics (mean ± stddev) if
0115   /// logging is enabled at the configured level.
0116   /// Exceptions from formatting or logging terminate the process.
0117   ~AveragingScopedTimer() noexcept;
0118   AveragingScopedTimer(const AveragingScopedTimer&) = delete;
0119   AveragingScopedTimer& operator=(const AveragingScopedTimer&) = delete;
0120   AveragingScopedTimer(AveragingScopedTimer&&) = delete;
0121   AveragingScopedTimer& operator=(AveragingScopedTimer&&) = delete;
0122 
0123   /// @brief Create a new timing sample
0124   ///
0125   /// @return Sample RAII wrapper for measuring a single timing sample
0126   Sample sample();
0127 
0128   friend class Sample;
0129 
0130  private:
0131   /// @brief Add a timing sample to the statistics
0132   ///
0133   /// @param duration Duration of the sample in nanoseconds
0134   void addSample(std::chrono::nanoseconds duration);
0135 
0136   /// Accumulators are atomic so samples can be recorded concurrently from
0137   /// multiple threads. Relaxed ordering is sufficient because sample completion
0138   /// must be synchronized with timer destruction, making all updates visible
0139   /// before the destructor reads the aggregate values.
0140   std::atomic<double> m_sumDuration{0};  ///< Sum of all sample durations
0141   std::atomic<double> m_sumDurationSquared{
0142       0};  ///< Sum of squared durations for stddev calculation
0143   std::atomic<std::size_t> m_nSamples{0};  ///< Number of samples recorded
0144 
0145   std::string m_name;      ///< Name of the timer for logging
0146   Logging::Level m_lvl;    ///< Logging level for output
0147   const Logger* m_logger;  ///< Logger instance for output
0148 };
0149 }  // namespace Acts