Rcpp Version 1.0.9
Timer.h
Go to the documentation of this file.
1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 //
3 // Timer.h: Rcpp R/C++ interface class library -- Rcpp benchmark utility
4 //
5 // Copyright (C) 2012 - 2014 JJ Allaire, Dirk Eddelbuettel and Romain Francois
6 //
7 // This file is part of Rcpp.
8 //
9 // Rcpp is free software: you can redistribute it and/or modify it
10 // under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // Rcpp is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
21 
22 #ifndef RCPP_BENCHMARH_TIMER_H
23 #define RCPP_BENCHMARH_TIMER_H
24 
25 #include <stdint.h>
26 #include <vector>
27 #include <string>
28 
29 #define R_NO_REMAP
30 #include <Rinternals.h>
31 
32 #if defined(_WIN32)
33  #define WIN32_LEAN_AND_MEAN
34  #include <windows.h>
35 #elif defined(__APPLE__)
36  #include <mach/mach_time.h>
37 #elif defined(linux) || defined(__linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__GLIBC__) || defined(__GNU__) || defined(__CYGWIN__)
38  #include <time.h>
39 #elif defined(sun) || defined(__sun) || defined(_AIX)
40  #include <sys/time.h>
41 #else /* Unsupported OS */
42  #error "Rcpp::Timer not supported by your OS."
43 #endif
44 
45 namespace Rcpp{
46 
47  typedef uint64_t nanotime_t;
48 
49 #if defined(_WIN32)
50 
51  inline nanotime_t get_nanotime(void) {
52  LARGE_INTEGER time_var, frequency;
53  QueryPerformanceCounter(&time_var);
54  QueryPerformanceFrequency(&frequency);
55 
56  /* Convert to nanoseconds */
57  return 1.0e9 * time_var.QuadPart / frequency.QuadPart;
58  }
59 
60 #elif defined(__APPLE__)
61 
62  inline nanotime_t get_nanotime(void) {
63  nanotime_t time;
64  mach_timebase_info_data_t info;
65 
66  time = mach_absolute_time();
67  mach_timebase_info(&info);
68 
69  /* Convert to nanoseconds */
70  return time * (info.numer / info.denom);
71  }
72 
73 #elif defined(linux) || defined(__linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__GLIBC__) || defined(__GNU__) || defined(__CYGWIN__)
74 
75  static const nanotime_t nanoseconds_in_second = static_cast<nanotime_t>(1000000000.0);
76 
77  inline nanotime_t get_nanotime(void) {
78  struct timespec time_var;
79 
80  /* Possible other values we could have used are CLOCK_MONOTONIC,
81  * which is takes longer to retrieve and CLOCK_PROCESS_CPUTIME_ID
82  * which, if I understand it correctly, would require the R
83  * process to be bound to one core.
84  */
85  clock_gettime(CLOCK_REALTIME, &time_var);
86 
87  nanotime_t sec = time_var.tv_sec;
88  nanotime_t nsec = time_var.tv_nsec;
89 
90  /* Combine both values to one nanoseconds value */
91  return (nanoseconds_in_second * sec) + nsec;
92  }
93 
94 #elif defined(sun) || defined(__sun) || defined(_AIX)
95 
96  /* short an sweet! */
97  inline nanotime_t get_nanotime(void) {
98  return gethrtime();
99  }
100 
101 #endif
102 
103  class Timer {
104  public:
105  Timer() : data(), start_time( get_nanotime() ){}
106  Timer(nanotime_t start_time_) : data(), start_time(start_time_){}
107 
108  void step( const std::string& name){
109  data.push_back(std::make_pair(name, now()));
110  }
111 
112  operator SEXP() const {
113  size_t n = data.size();
114  NumericVector out(n);
115  CharacterVector names(n);
116  for (size_t i=0; i<n; i++) {
117  names[i] = data[i].first;
118  out[i] = data[i].second - start_time ;
119  }
120  out.attr("names") = names;
121  return out;
122  }
123 
124  static std::vector<Timer> get_timers(int n){
125  return std::vector<Timer>( n, Timer() ) ;
126  }
127 
128  inline nanotime_t now() const {
129  return get_nanotime() ;
130  }
131 
132  inline nanotime_t origin() const {
133  return start_time ;
134  }
135 
136  private:
137  typedef std::pair<std::string,nanotime_t> Step;
138  typedef std::vector<Step> Steps;
139 
142  };
143 
144 }
145 
146 #ifdef FALSE
147  #undef FALSE
148 #endif
149 
150 #endif
AttributeProxy attr(const std::string &name)
Steps data
Definition: Timer.h:140
Timer(nanotime_t start_time_)
Definition: Timer.h:106
std::vector< Step > Steps
Definition: Timer.h:138
nanotime_t now() const
Definition: Timer.h:128
const nanotime_t start_time
Definition: Timer.h:141
nanotime_t origin() const
Definition: Timer.h:132
void step(const std::string &name)
Definition: Timer.h:108
static std::vector< Timer > get_timers(int n)
Definition: Timer.h:124
std::pair< std::string, nanotime_t > Step
Definition: Timer.h:137
Rcpp API.
Definition: algo.h:28
uint64_t nanotime_t
Definition: Timer.h:47