Ninja
metrics.cc
Go to the documentation of this file.
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "metrics.h"
16 
17 #include <errno.h>
18 #include <stdio.h>
19 #include <string.h>
20 
21 #ifndef _WIN32
22 #include <sys/time.h>
23 #else
24 #include <windows.h>
25 #endif
26 
27 #include <algorithm>
28 
29 #include "util.h"
30 
32 
33 namespace {
34 
35 #ifndef _WIN32
36 /// Compute a platform-specific high-res timer value that fits into an int64.
37 int64_t HighResTimer() {
38  timeval tv;
39  if (gettimeofday(&tv, NULL) < 0)
40  Fatal("gettimeofday: %s", strerror(errno));
41  return (int64_t)tv.tv_sec * 1000*1000 + tv.tv_usec;
42 }
43 
44 /// Convert a delta of HighResTimer() values to microseconds.
45 int64_t TimerToMicros(int64_t dt) {
46  // No conversion necessary.
47  return dt;
48 }
49 #else
50 int64_t LargeIntegerToInt64(const LARGE_INTEGER& i) {
51  return ((int64_t)i.HighPart) << 32 | i.LowPart;
52 }
53 
54 int64_t HighResTimer() {
55  LARGE_INTEGER counter;
56  if (!QueryPerformanceCounter(&counter))
57  Fatal("QueryPerformanceCounter: %s", GetLastErrorString().c_str());
58  return LargeIntegerToInt64(counter);
59 }
60 
61 int64_t TimerToMicros(int64_t dt) {
62  static int64_t ticks_per_sec = 0;
63  if (!ticks_per_sec) {
64  LARGE_INTEGER freq;
65  if (!QueryPerformanceFrequency(&freq))
66  Fatal("QueryPerformanceFrequency: %s", GetLastErrorString().c_str());
67  ticks_per_sec = LargeIntegerToInt64(freq);
68  }
69 
70  // dt is in ticks. We want microseconds.
71  return (dt * 1000000) / ticks_per_sec;
72 }
73 #endif
74 
75 } // anonymous namespace
76 
77 
79  metric_ = metric;
80  if (!metric_)
81  return;
82  start_ = HighResTimer();
83 }
85  if (!metric_)
86  return;
87  metric_->count++;
88  int64_t dt = TimerToMicros(HighResTimer() - start_);
89  metric_->sum += dt;
90 }
91 
92 Metric* Metrics::NewMetric(const string& name) {
93  Metric* metric = new Metric;
94  metric->name = name;
95  metric->count = 0;
96  metric->sum = 0;
97  metrics_.push_back(metric);
98  return metric;
99 }
100 
102  int width = 0;
103  for (vector<Metric*>::iterator i = metrics_.begin();
104  i != metrics_.end(); ++i) {
105  width = max((int)(*i)->name.size(), width);
106  }
107 
108  printf("%-*s\t%-6s\t%-9s\t%s\n", width,
109  "metric", "count", "avg (us)", "total (ms)");
110  for (vector<Metric*>::iterator i = metrics_.begin();
111  i != metrics_.end(); ++i) {
112  Metric* metric = *i;
113  double total = metric->sum / (double)1000;
114  double avg = metric->sum / (double)metric->count;
115  printf("%-*s\t%-6d\t%-8.1f\t%.1f\n", width, metric->name.c_str(),
116  metric->count, avg, total);
117  }
118 }
119 
121  return TimerToMicros(HighResTimer());
122 }
123 
125  return TimerToMicros(HighResTimer()) / 1000;
126 }
127 
ScopedMetric(Metric *metric)
Definition: metrics.cc:78
void Report()
Print a summary report to stdout.
Definition: metrics.cc:101
int64_t start_
Timestamp when the measurement started.
Definition: metrics.h:47
int64_t sum
Total time (in micros) we've spent on the code path.
Definition: metrics.h:33
int count
Number of times we've hit the code path.
Definition: metrics.h:31
int64_t GetTimeMillis()
Get the current time as relative to some epoch.
Definition: metrics.cc:124
Metrics * g_metrics
Definition: metrics.cc:31
vector< Metric * > metrics_
Definition: metrics.h:58
string name
Definition: metrics.h:29
The Metrics module is used for the debug mode that dumps timing stats of various actions.
Definition: metrics.h:28
signed long long int64_t
A 64-bit integer type.
Definition: win32port.h:21
uint64_t Now() const
Definition: metrics.cc:120
~ScopedMetric()
Definition: metrics.cc:84
Metric * NewMetric(const string &name)
Definition: metrics.cc:92
void Fatal(const char *msg,...)
Log a fatal message and exit.
Definition: util.cc:52
The singleton that stores metrics and prints the report.
Definition: metrics.h:51
Metric * metric_
Definition: metrics.h:44
unsigned long long uint64_t
Definition: win32port.h:22