OR-Tools  8.2
stats.cc
Go to the documentation of this file.
1// Copyright 2010-2018 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#include "ortools/util/stats.h"
15
16#include <cmath>
17
18#include "absl/strings/str_format.h"
21#include "ortools/port/utf8.h"
22
23namespace operations_research {
24
25std::string MemoryUsage() {
27 static const int64 kDisplayThreshold = 2;
28 static const int64 kKiloByte = 1024;
29 static const int64 kMegaByte = kKiloByte * kKiloByte;
30 static const int64 kGigaByte = kMegaByte * kKiloByte;
31 if (mem > kDisplayThreshold * kGigaByte) {
32 return absl::StrFormat("%.2lf GB", mem * 1.0 / kGigaByte);
33 } else if (mem > kDisplayThreshold * kMegaByte) {
34 return absl::StrFormat("%.2lf MB", mem * 1.0 / kMegaByte);
35 } else if (mem > kDisplayThreshold * kKiloByte) {
36 return absl::StrFormat("%2lf KB", mem * 1.0 / kKiloByte);
37 } else {
38 return absl::StrFormat("%d", mem);
39 }
40}
41
42Stat::Stat(const std::string& name, StatsGroup* group) : name_(name) {
43 group->Register(this);
44}
45
46std::string Stat::StatString() const { return name_ + ": " + ValueAsString(); }
47
49
50void StatsGroup::Register(Stat* stat) { stats_.push_back(stat); }
51
53 for (int i = 0; i < stats_.size(); ++i) {
54 stats_[i]->Reset();
55 }
56}
57
58namespace {
59
60bool CompareStatPointers(const Stat* s1, const Stat* s2) {
61 if (s1->Priority() == s2->Priority()) {
62 if (s1->Sum() == s2->Sum()) return s1->Name() < s2->Name();
63 return (s1->Sum() > s2->Sum());
64 } else {
65 return (s1->Priority() > s2->Priority());
66 }
67}
68
69} // namespace
70
71std::string StatsGroup::StatString() const {
72 // Computes the longest name of all the stats we want to display.
73 // Also create a temporary vector so we can sort the stats by names.
74 int longest_name_size = 0;
75 std::vector<Stat*> sorted_stats;
76 for (int i = 0; i < stats_.size(); ++i) {
77 if (!stats_[i]->WorthPrinting()) continue;
78 // We support UTF8 characters in the stat names.
79 const int size = operations_research::utf8::UTF8StrLen(stats_[i]->Name());
80 longest_name_size = std::max(longest_name_size, size);
81 sorted_stats.push_back(stats_[i]);
82 }
83 switch (print_order_) {
85 std::sort(sorted_stats.begin(), sorted_stats.end(), CompareStatPointers);
86 break;
87 case SORT_BY_NAME:
88 std::sort(sorted_stats.begin(), sorted_stats.end(),
89 [](const Stat* s1, const Stat* s2) -> bool {
90 return s1->Name() < s2->Name();
91 });
92 break;
93 default:
94 LOG(FATAL) << "Unknown print order: " << print_order_;
95 }
96
97 // Do not display groups without print-worthy stats.
98 if (sorted_stats.empty()) return "";
99
100 // Pretty-print all the stats.
101 std::string result(name_ + " {\n");
102 for (int i = 0; i < sorted_stats.size(); ++i) {
103 result += " ";
104 result += sorted_stats[i]->Name();
105 result.append(longest_name_size - operations_research::utf8::UTF8StrLen(
106 sorted_stats[i]->Name()),
107 ' ');
108 result += " : " + sorted_stats[i]->ValueAsString();
109 }
110 result += "}\n";
111 return result;
112}
113
115 TimeDistribution*& ref = time_distributions_[name];
116 if (ref == nullptr) {
117 ref = new TimeDistribution(name);
118 Register(ref);
119 }
120 return ref;
121}
122
124 : Stat(name),
125 sum_(0.0),
126 average_(0.0),
127 sum_squares_from_average_(0.0),
128 min_(0.0),
129 max_(0.0),
130 num_(0) {}
131
133 : Stat(name, group),
134 sum_(0.0),
135 average_(0.0),
136 sum_squares_from_average_(0.0),
137 min_(0.0),
138 max_(0.0),
139 num_(0) {}
140
142 sum_ = 0.0;
143 average_ = 0.0;
145 min_ = 0.0;
146 max_ = 0.0;
147 num_ = 0;
148}
149
151 if (num_ == 0) {
152 min_ = value;
153 max_ = value;
154 sum_ = value;
155 average_ = value;
156 num_ = 1;
157 return;
158 }
161 sum_ += value;
162 ++num_;
163 const double delta = value - average_;
164 average_ = sum_ / num_;
166}
167
168double DistributionStat::Average() const { return average_; }
169
171 if (num_ == 0) return 0.0;
172 return sqrt(sum_squares_from_average_ / num_);
173}
174
176 const double seconds_per_cycles = CycleTimerBase::CyclesToSeconds(1);
177 return cycles * seconds_per_cycles;
178}
179
180std::string TimeDistribution::PrintCyclesAsTime(double cycles) {
181 DCHECK_GE(cycles, 0.0);
182 // This epsilon is just to avoid displaying 1000.00ms instead of 1.00s.
183 double eps1 = 1 + 1e-3;
184 double sec = CyclesToSeconds(cycles);
185 if (sec * eps1 >= 3600.0) return absl::StrFormat("%.2fh", sec / 3600.0);
186 if (sec * eps1 >= 60.0) return absl::StrFormat("%.2fm", sec / 60.0);
187 if (sec * eps1 >= 1.0) return absl::StrFormat("%.2fs", sec);
188 if (sec * eps1 >= 1e-3) return absl::StrFormat("%.2fms", sec * 1e3);
189 if (sec * eps1 >= 1e-6) return absl::StrFormat("%.2fus", sec * 1e6);
190 return absl::StrFormat("%.2fns", sec * 1e9);
191}
192
193void TimeDistribution::AddTimeInSec(double seconds) {
194 DCHECK_GE(seconds, 0.0);
195 const double cycles_per_seconds = 1.0 / CycleTimerBase::CyclesToSeconds(1);
196 AddToDistribution(seconds * cycles_per_seconds);
197}
198
200 DCHECK_GE(cycles, 0.0);
201 AddToDistribution(cycles);
202}
203
205 return absl::StrFormat(
206 "%8u [%8s, %8s] %8s %8s %8s\n", num_, PrintCyclesAsTime(min_),
207 PrintCyclesAsTime(max_), PrintCyclesAsTime(Average()),
208 PrintCyclesAsTime(StdDeviation()), PrintCyclesAsTime(sum_));
209}
210
212 DCHECK_GE(value, 0.0);
214}
215
217 return absl::StrFormat("%8u [%7.2f%%, %7.2f%%] %7.2f%% %7.2f%%\n", num_,
218 100.0 * min_, 100.0 * max_, 100.0 * Average(),
219 100.0 * StdDeviation());
220}
221
223
225 return absl::StrFormat("%8u [%8.1e, %8.1e] %8.1e %8.1e\n", num_, min_, max_,
226 Average(), StdDeviation());
227}
228
230 AddToDistribution(static_cast<double>(value));
231}
232
234 return absl::StrFormat("%8u [%8.f, %8.f] %8.2f %8.2f %8.f\n", num_, min_,
236}
237
238#ifdef HAS_PERF_SUBSYSTEM
239EnabledScopedInstructionCounter::EnabledScopedInstructionCounter(
240 const std::string& name, TimeLimit* time_limit)
241 : time_limit_(time_limit), name_(name) {
242 starting_count_ =
243 time_limit_ != nullptr ? time_limit_->ReadInstructionCounter() : 0;
244}
245
246EnabledScopedInstructionCounter::~EnabledScopedInstructionCounter() {
247 ending_count_ =
248 time_limit_ != nullptr ? time_limit_->ReadInstructionCounter() : 0;
249 LOG(INFO) << name_ << ", Instructions: " << ending_count_ - starting_count_;
250}
251#endif // HAS_PERF_SUBSYSTEM
252
253} // namespace operations_research
int64 min
Definition: alldiff_cst.cc:138
int64 max
Definition: alldiff_cst.cc:139
#define DCHECK_GE(val1, val2)
Definition: base/logging.h:889
#define LOG(severity)
Definition: base/logging.h:420
static double CyclesToSeconds(int64 c)
Definition: timer.h:85
void AddToDistribution(double value)
Definition: stats.cc:150
std::string ValueAsString() const override
Definition: stats.cc:224
std::string ValueAsString() const override
Definition: stats.cc:233
std::string ValueAsString() const override
Definition: stats.cc:216
virtual std::string ValueAsString() const =0
std::string Name() const
Definition: stats.h:102
virtual double Sum() const
Definition: stats.h:115
virtual int Priority() const
Definition: stats.h:111
Stat(const std::string &name)
Definition: stats.h:95
std::string StatString() const
Definition: stats.cc:46
void Register(Stat *stat)
Definition: stats.cc:50
TimeDistribution * LookupOrCreateTimeDistribution(std::string name)
Definition: stats.cc:114
std::string StatString() const
Definition: stats.cc:71
static double CyclesToSeconds(double num_cycles)
Definition: stats.cc:175
void AddTimeInCycles(double cycles)
Definition: stats.cc:199
void AddTimeInSec(double seconds)
Definition: stats.cc:193
std::string ValueAsString() const override
Definition: stats.cc:204
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
Definition: time_limit.h:105
SharedTimeLimit * time_limit
const std::string name
int64 value
int64_t int64
const int INFO
Definition: log_severity.h:31
const int FATAL
Definition: log_severity.h:32
void STLDeleteValues(T *v)
Definition: stl_util.h:382
int UTF8StrLen(StrType str_type)
Definition: utf8.h:28
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
std::string MemoryUsage()
Definition: stats.cc:25
int64 delta
Definition: resource.cc:1684