/* Cadabra: a field-theory motivated computer algebra system. Copyright (C) 2001-2011 Kasper Peeters This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef stopwatch_hh__ #define stopwatch_hh__ #include #include #include /// \class Stopwatch /// \ingroup Client-Server /// /// The Stopwach class provides a simple interace to allow /// timing function calls etc... It is possible to stop /// the stopwatch for an indefinite amount of time without /// losing the current elapsed time period, allowing it /// to be used to calculate the actual amount of time /// a function spends performing a task without taking /// into account e.g. time spent being blocked by a mutex. /// The class is exported to python in the cadabra2 /// module as Stopwatch. /// /// /// Example C++ usage: /// /// ~~~~~~~{.cc} /// #include /// #include /// #include "Stopwatch.hh" /// /// void do_other_stuff() { std::cout << "Doing other stuff\n"; } /// /// int main() /// { /// const int n = 1000; /// std::vector v; /// Stopwatch s; /// /// s.start(); /// for (unsigned int i = 0; i < n; ++i) /// v.push_back(i); /// s.stop(); /// do_other_stuff(); /// s.start(); /// for (unsigned int i = n; i > 0; --i) /// v.push_back(i); /// s.stop(); /// std::cout << "Total time spent pushing to vector and not spent doing other stuff: " << s << '\n'; /// /// s.reset(); /// s.start(); /// do_other_stuff(); /// s.stop(); /// std::cout << "Doing other stuff takes " << s.useconds() << "us\n"; //Assuming do_other_stuff() takes < 1s /// return 0; /// } /// ~~~~~~~ /// /// Example python usage: /// /// ~~~~~~~{.py} /// from cadabra2 import Stopwatch /// /// def do_other_stuff(): /// print("Doing other stuff") /// /// n = 1000 /// v = [] /// s = Stopwatch() /// /// s.start() /// for i in range(n): /// v += [i] /// s.stop() /// do_other_stuff() /// s.start() /// for i in range(n, 0, -1): /// v += [i] /// s.stop() /// print("Total time spent pushing to vector and not spent doing other stuff: {}".format(s)) /// /// s.reset() /// s.start() /// do_other_stuff() /// s.stop() /// print("Doing other stuff takes {}us".format(s.useconds())) #Assuming do_other_stuff() takes < 1s /// ~~~~~~~ class Stopwatch { public: Stopwatch(); typedef std::chrono::steady_clock clock; /// Reset to no-time-elapsed. void reset(); /// Continue timing (does not reset). void start(); /// Stop timing. void stop(); /// Number of seconds elapsed. long seconds() const; /// Number of micro-seconds elapsed (needs to be added to 'seconds'). long useconds() const; /// Is the stopwatch currently timing? bool stopped() const; friend std::ostream& operator<<(std::ostream&, const Stopwatch&); private: void checkpoint_() const; mutable clock::time_point start_; mutable long elapsed_; bool stopped_; static const long s_to_us = 1000000L; }; /// Print human-readable representation of the time elapsed. std::ostream& operator<<(std::ostream&, const Stopwatch&); #endif