OR-Tools  8.1
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"
19 #include "ortools/base/stl_util.h"
20 #include "ortools/port/sysinfo.h"
21 #include "ortools/port/utf8.h"
22 
23 namespace operations_research {
24 
25 std::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 
42 Stat::Stat(const std::string& name, StatsGroup* group) : name_(name) {
43  group->Register(this);
44 }
45 
46 std::string Stat::StatString() const { return name_ + ": " + ValueAsString(); }
47 
48 StatsGroup::~StatsGroup() { gtl::STLDeleteValues(&time_distributions_); }
49 
50 void 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 
58 namespace {
59 
60 bool 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 
71 std::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  }
159  min_ = std::min(min_, value);
160  max_ = std::max(max_, value);
161  sum_ += value;
162  ++num_;
163  const double delta = value - average_;
164  average_ = sum_ / num_;
166 }
167 
168 double DistributionStat::Average() const { return average_; }
169 
171  if (num_ == 0) return 0.0;
172  return sqrt(sum_squares_from_average_ / num_);
173 }
174 
175 double TimeDistribution::CyclesToSeconds(double cycles) {
176  const double seconds_per_cycles = CycleTimerBase::CyclesToSeconds(1);
177  return cycles * seconds_per_cycles;
178 }
179 
180 std::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 
193 void 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 
204 std::string TimeDistribution::ValueAsString() const {
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 
216 std::string RatioDistribution::ValueAsString() const {
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_,
235  max_, Average(), StdDeviation(), sum_);
236 }
237 
238 #ifdef HAS_PERF_SUBSYSTEM
239 EnabledScopedInstructionCounter::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 
246 EnabledScopedInstructionCounter::~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
operations_research::IntegerDistribution::ValueAsString
std::string ValueAsString() const override
Definition: stats.cc:233
INFO
const int INFO
Definition: log_severity.h:31
operations_research::Stat
Definition: stats.h:93
operations_research::sysinfo::MemoryUsageProcess
int64 MemoryUsageProcess()
Definition: sysinfo_nonport.cc:20
min
int64 min
Definition: alldiff_cst.cc:138
max
int64 max
Definition: alldiff_cst.cc:139
operations_research::DistributionStat::num_
int64 num_
Definition: stats.h:211
operations_research::DoubleDistribution::Add
void Add(double value)
Definition: stats.cc:222
operations_research::DistributionStat::AddToDistribution
void AddToDistribution(double value)
Definition: stats.cc:150
LOG
#define LOG(severity)
Definition: base/logging.h:420
operations_research::StatsGroup
Definition: stats.h:131
operations_research::Stat::Priority
virtual int Priority() const
Definition: stats.h:111
FATAL
const int FATAL
Definition: log_severity.h:32
operations_research::StatsGroup::LookupOrCreateTimeDistribution
TimeDistribution * LookupOrCreateTimeDistribution(std::string name)
Definition: stats.cc:114
operations_research::DistributionStat::Average
double Average() const
Definition: stats.cc:168
operations_research::DoubleDistribution::ValueAsString
std::string ValueAsString() const override
Definition: stats.cc:224
value
int64 value
Definition: demon_profiler.cc:43
operations_research::RatioDistribution::ValueAsString
std::string ValueAsString() const override
Definition: stats.cc:216
operations_research::DistributionStat::min_
double min_
Definition: stats.h:209
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
operations_research::Stat::Stat
Stat(const std::string &name)
Definition: stats.h:95
operations_research::TimeDistribution::ValueAsString
std::string ValueAsString() const override
Definition: stats.cc:204
operations_research::MemoryUsage
std::string MemoryUsage()
Definition: stats.cc:25
operations_research::Stat::Sum
virtual double Sum() const
Definition: stats.h:115
sysinfo.h
int64
int64_t int64
Definition: integral_types.h:34
operations_research::RatioDistribution::Add
void Add(double value)
Definition: stats.cc:211
operations_research::StatsGroup::~StatsGroup
~StatsGroup()
Definition: stats.cc:48
operations_research::Stat::StatString
std::string StatString() const
Definition: stats.cc:46
operations_research::StatsGroup::SORT_BY_PRIORITY_THEN_VALUE
@ SORT_BY_PRIORITY_THEN_VALUE
Definition: stats.h:134
operations_research::StatsGroup::SORT_BY_NAME
@ SORT_BY_NAME
Definition: stats.h:135
operations_research::DistributionStat::StdDeviation
double StdDeviation() const
Definition: stats.cc:170
operations_research::TimeLimit
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
Definition: time_limit.h:105
stats.h
operations_research::TimeDistribution::AddTimeInCycles
void AddTimeInCycles(double cycles)
Definition: stats.cc:199
time_limit
SharedTimeLimit * time_limit
Definition: cp_model_solver.cc:2103
operations_research::StatsGroup::Reset
void Reset()
Definition: stats.cc:52
operations_research::TimeDistribution::AddTimeInSec
void AddTimeInSec(double seconds)
Definition: stats.cc:193
operations_research::TimeDistribution
Definition: stats.h:221
operations_research::DistributionStat::Reset
void Reset() override
Definition: stats.cc:141
operations_research::TimeDistribution::CyclesToSeconds
static double CyclesToSeconds(double num_cycles)
Definition: stats.cc:175
operations_research::StatsGroup::Register
void Register(Stat *stat)
Definition: stats.cc:50
operations_research::Stat::Name
std::string Name() const
Definition: stats.h:102
CycleTimerBase::CyclesToSeconds
static double CyclesToSeconds(int64 c)
Definition: timer.h:85
DCHECK_GE
#define DCHECK_GE(val1, val2)
Definition: base/logging.h:889
operations_research::DistributionStat::average_
double average_
Definition: stats.h:207
utf8.h
stl_util.h
delta
int64 delta
Definition: resource.cc:1684
operations_research::utf8::UTF8StrLen
int UTF8StrLen(StrType str_type)
Definition: utf8.h:28
operations_research::DistributionStat::sum_squares_from_average_
double sum_squares_from_average_
Definition: stats.h:208
operations_research::DistributionStat::sum_
double sum_
Definition: stats.h:206
operations_research::StatsGroup::StatString
std::string StatString() const
Definition: stats.cc:71
operations_research::Stat::ValueAsString
virtual std::string ValueAsString() const =0
operations_research::DistributionStat::DistributionStat
DistributionStat()
Definition: stats.h:178
operations_research::DistributionStat::max_
double max_
Definition: stats.h:210
name
const std::string name
Definition: default_search.cc:808
gtl::STLDeleteValues
void STLDeleteValues(T *v)
Definition: stl_util.h:382
operations_research::IntegerDistribution::Add
void Add(int64 value)
Definition: stats.cc:229