Program Listing for File timers.h

Return to documentation for file (include/aruco/timers.h)

#ifndef ARUCO_TIMERS_H
#define ARUCO_TIMERS_H


#include <chrono>
#include <string>
#include <vector>
#include <iostream>
#include "aruco_export.h"
namespace aruco
{

// timer
struct ScopeTimer
{
  std::chrono::high_resolution_clock::time_point begin, end;

  std::string name;
  bool use;
  enum SCALE
  {
    NSEC,
    MSEC,
    SEC
  };
  SCALE sc;
  ScopeTimer(std::string name_, bool use_ = true, SCALE _sc = MSEC)
  {
#ifdef USE_TIMERS
    name = name_;
    use = use_;
    sc = _sc;
    begin = std::chrono::high_resolution_clock::now();
#else
    (void)name_;
    (void)use_;
    (void)_sc;

#endif
  }
  ~ScopeTimer()
  {
#ifdef USE_TIMERS
    if (use)
    {
      end = std::chrono::high_resolution_clock::now();
      double fact = 1;
      std::string str;
      switch (sc)
      {
        case NSEC:
          fact = 1;
          str = "ns";
          break;
        case MSEC:
          fact = 1e6;
          str = "ms";
          break;
        case SEC:
          fact = 1e9;
          str = "s";
          break;
      };

      std::cout << "Time(" << name << ")= "
                << double(
                       std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin).count()) /
                       fact
                << str << std::endl;
      ;
    }
#endif
  }
};

struct ScopedTimerEvents
{
  enum SCALE
  {
    NSEC,
    MSEC,
    SEC
  };
  SCALE sc;
  std::vector<std::chrono::high_resolution_clock::time_point> vtimes;
  std::vector<std::string> names;
  std::string _name;

  ScopedTimerEvents(std::string name = "", bool start = true, SCALE _sc = MSEC)
  {
#ifdef USE_TIMERS
    if (start)
      add("start");
    sc = _sc;
    _name = name;
#else
    (void)name;
    (void)start;
    (void)_sc;
#endif
  }

  void add(std::string name)
  {
#ifdef USE_TIMERS
    vtimes.push_back(std::chrono::high_resolution_clock::now());
    names.push_back(name);
#else
    (void)name;
#endif
  }
  void addspaces(std::vector<std::string> &str)
  {
    // get max size
    size_t m = 0;
    for (auto &s : str)
      m = std::max(size_t(s.size()), m);
    for (auto &s : str)
    {
      while (s.size() < m)
        s.push_back(' ');
    }
  }

  ~ScopedTimerEvents()
  {
#ifdef USE_TIMERS
    double fact = 1;
    std::string str;
    switch (sc)
    {
      case NSEC:
        fact = 1;
        str = "ns";
        break;
      case MSEC:
        fact = 1e6;
        str = "ms";
        break;
      case SEC:
        fact = 1e9;
        str = "s";
        break;
    };

    add("total");
    addspaces(names);
    for (size_t i = 1; i < vtimes.size(); i++)
    {
      std::cout << "Time(" << _name << "|" << names[i] << " ):"
                << double(std::chrono::duration_cast<std::chrono::nanoseconds>(
                              vtimes[i] - vtimes[i - 1])
                              .count()) /
                       fact
                << str << " "
                << double(std::chrono::duration_cast<std::chrono::nanoseconds>(vtimes[i] -
                                                                               vtimes[0])
                              .count()) /
                       fact
                << str /*<<"\t"<< vtimes[i].time_since_epoch().count()*/ << std::endl;
    }
#endif
  }
};

struct ARUCO_EXPORT Timer
{
  enum SCALE
  {
    NSEC,
    MSEC,
    SEC
  };

  std::chrono::high_resolution_clock::time_point _s;
  double sum = 0, n = 0;
  std::string _name;
  Timer()
  {
  }

  Timer(std::string name) : _name(name)
  {
  }
  void setName(std::string name)
  {
    _name = name;
  }
  void start()
  {
    _s = std::chrono::high_resolution_clock::now();
  }
  void end()
  {
    auto e = std::chrono::high_resolution_clock::now();
    sum += double(std::chrono::duration_cast<std::chrono::nanoseconds>(e - _s).count());
    n++;
  }

  void print(SCALE sc = MSEC)
  {
#ifdef USE_TIMERS
    double fact = 1;
    std::string str;
    switch (sc)
    {
      case NSEC:
        fact = 1;
        str = "ns";
        break;
      case MSEC:
        fact = 1e6;
        str = "ms";
        break;
      case SEC:
        fact = 1e9;
        str = "s";
        break;
    };
    std::cout << "Time(" << _name << ")= " << (sum / n) / fact << str << std::endl;
#else
    (void)sc;

#endif
  }

  double getAverage(SCALE sc = MSEC) const
  {
    double fact = 1;
    switch (sc)
    {
      case NSEC:
        fact = 1;
        break;
      case MSEC:
        fact = 1e6;
        break;
      case SEC:
        fact = 1e9;
        break;
    };
    return (sum / n) / fact;
  }
};
inline std::string __pf_aruco_methodName(std::string prettyFunction)
{
  std::string res;
  res.reserve(prettyFunction.size());
  bool spaceFound = false;
  for (auto c : prettyFunction)
  {
    if (c == ' ' && !spaceFound)
      spaceFound = true;
    else if (c != '(' && spaceFound)
      res.push_back(c);
    else if (c == '(' && spaceFound)
      break;
  }
  return res;
}
#ifdef USE_TIMERS

#define __ARUCO_ADDTIMER__                                                               \
  ScopedTimerEvents XTIMER_X(__pf_aruco_methodName(__PRETTY_FUNCTION__));
#define __ARUCO_TIMER_EVENT__(Y) XTIMER_X.add(Y);
#else
#define __ARUCO_ADDTIMER__
#define __ARUCO_TIMER_EVENT__(Y)
#endif
}  // namespace aruco


#endif