xref: /aosp_15_r20/external/pigweed/pw_allocator/benchmarks/measurements.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker // Copyright 2024 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker 
15*61c4878aSAndroid Build Coastguard Worker #include "pw_allocator/benchmarks/measurements.h"
16*61c4878aSAndroid Build Coastguard Worker 
17*61c4878aSAndroid Build Coastguard Worker namespace pw::allocator {
18*61c4878aSAndroid Build Coastguard Worker namespace internal {
19*61c4878aSAndroid Build Coastguard Worker 
20*61c4878aSAndroid Build Coastguard Worker // GenericMeasurement methods
21*61c4878aSAndroid Build Coastguard Worker 
GenericMeasurement(metric::Token name)22*61c4878aSAndroid Build Coastguard Worker GenericMeasurement::GenericMeasurement(metric::Token name) : metrics_(name) {
23*61c4878aSAndroid Build Coastguard Worker   metrics_.Add(nanoseconds_);
24*61c4878aSAndroid Build Coastguard Worker   metrics_.Add(fragmentation_);
25*61c4878aSAndroid Build Coastguard Worker   metrics_.Add(largest_);
26*61c4878aSAndroid Build Coastguard Worker   metrics_.Add(failures_);
27*61c4878aSAndroid Build Coastguard Worker }
28*61c4878aSAndroid Build Coastguard Worker 
Update(const BenchmarkSample & data)29*61c4878aSAndroid Build Coastguard Worker void GenericMeasurement::Update(const BenchmarkSample& data) {
30*61c4878aSAndroid Build Coastguard Worker   count_++;
31*61c4878aSAndroid Build Coastguard Worker 
32*61c4878aSAndroid Build Coastguard Worker   float mean = nanoseconds_.value();
33*61c4878aSAndroid Build Coastguard Worker   mean += (data.nanoseconds - mean) / count_;
34*61c4878aSAndroid Build Coastguard Worker   nanoseconds_.Set(mean);
35*61c4878aSAndroid Build Coastguard Worker 
36*61c4878aSAndroid Build Coastguard Worker   mean = fragmentation_.value();
37*61c4878aSAndroid Build Coastguard Worker   mean += (data.fragmentation - mean) / count_;
38*61c4878aSAndroid Build Coastguard Worker   fragmentation_.Set(mean);
39*61c4878aSAndroid Build Coastguard Worker 
40*61c4878aSAndroid Build Coastguard Worker   mean = largest_.value();
41*61c4878aSAndroid Build Coastguard Worker   mean += (data.largest - mean) / count_;
42*61c4878aSAndroid Build Coastguard Worker   largest_.Set(mean);
43*61c4878aSAndroid Build Coastguard Worker 
44*61c4878aSAndroid Build Coastguard Worker   if (data.failed) {
45*61c4878aSAndroid Build Coastguard Worker     failures_.Increment();
46*61c4878aSAndroid Build Coastguard Worker   }
47*61c4878aSAndroid Build Coastguard Worker }
48*61c4878aSAndroid Build Coastguard Worker 
49*61c4878aSAndroid Build Coastguard Worker }  // namespace internal
50*61c4878aSAndroid Build Coastguard Worker 
51*61c4878aSAndroid Build Coastguard Worker // Measurements methods
52*61c4878aSAndroid Build Coastguard Worker 
Measurements(metric::Token name)53*61c4878aSAndroid Build Coastguard Worker Measurements::Measurements(metric::Token name) : metrics_(name) {
54*61c4878aSAndroid Build Coastguard Worker   metrics_.Add(metrics_by_count_);
55*61c4878aSAndroid Build Coastguard Worker   metrics_.Add(metrics_by_fragmentation_);
56*61c4878aSAndroid Build Coastguard Worker   metrics_.Add(metrics_by_size_);
57*61c4878aSAndroid Build Coastguard Worker }
58*61c4878aSAndroid Build Coastguard Worker 
AddByCount(Measurement<size_t> & measurement)59*61c4878aSAndroid Build Coastguard Worker void Measurements::AddByCount(Measurement<size_t>& measurement) {
60*61c4878aSAndroid Build Coastguard Worker   metrics_by_count_.Add(measurement.metrics());
61*61c4878aSAndroid Build Coastguard Worker   by_count_.insert(measurement);
62*61c4878aSAndroid Build Coastguard Worker }
63*61c4878aSAndroid Build Coastguard Worker 
AddByFragmentation(Measurement<float> & measurement)64*61c4878aSAndroid Build Coastguard Worker void Measurements::AddByFragmentation(Measurement<float>& measurement) {
65*61c4878aSAndroid Build Coastguard Worker   metrics_by_fragmentation_.Add(measurement.metrics());
66*61c4878aSAndroid Build Coastguard Worker   by_fragmentation_.insert(measurement);
67*61c4878aSAndroid Build Coastguard Worker }
68*61c4878aSAndroid Build Coastguard Worker 
AddBySize(Measurement<size_t> & measurement)69*61c4878aSAndroid Build Coastguard Worker void Measurements::AddBySize(Measurement<size_t>& measurement) {
70*61c4878aSAndroid Build Coastguard Worker   metrics_by_size_.Add(measurement.metrics());
71*61c4878aSAndroid Build Coastguard Worker   by_size_.insert(measurement);
72*61c4878aSAndroid Build Coastguard Worker }
73*61c4878aSAndroid Build Coastguard Worker 
Clear()74*61c4878aSAndroid Build Coastguard Worker void Measurements::Clear() {
75*61c4878aSAndroid Build Coastguard Worker   by_count_.clear();
76*61c4878aSAndroid Build Coastguard Worker   by_fragmentation_.clear();
77*61c4878aSAndroid Build Coastguard Worker   by_size_.clear();
78*61c4878aSAndroid Build Coastguard Worker }
79*61c4878aSAndroid Build Coastguard Worker 
GetByCount(size_t count)80*61c4878aSAndroid Build Coastguard Worker Measurement<size_t>& Measurements::GetByCount(size_t count) {
81*61c4878aSAndroid Build Coastguard Worker   PW_ASSERT(!by_count_.empty());
82*61c4878aSAndroid Build Coastguard Worker   auto iter = by_count_.upper_bound(count);
83*61c4878aSAndroid Build Coastguard Worker   if (iter != by_count_.begin()) {
84*61c4878aSAndroid Build Coastguard Worker     --iter;
85*61c4878aSAndroid Build Coastguard Worker   }
86*61c4878aSAndroid Build Coastguard Worker   return *iter;
87*61c4878aSAndroid Build Coastguard Worker }
88*61c4878aSAndroid Build Coastguard Worker 
GetByFragmentation(float fragmentation)89*61c4878aSAndroid Build Coastguard Worker Measurement<float>& Measurements::GetByFragmentation(float fragmentation) {
90*61c4878aSAndroid Build Coastguard Worker   PW_ASSERT(!by_fragmentation_.empty());
91*61c4878aSAndroid Build Coastguard Worker   auto iter = by_fragmentation_.upper_bound(fragmentation);
92*61c4878aSAndroid Build Coastguard Worker   if (iter != by_fragmentation_.begin()) {
93*61c4878aSAndroid Build Coastguard Worker     --iter;
94*61c4878aSAndroid Build Coastguard Worker   }
95*61c4878aSAndroid Build Coastguard Worker   return *iter;
96*61c4878aSAndroid Build Coastguard Worker }
97*61c4878aSAndroid Build Coastguard Worker 
GetBySize(size_t size)98*61c4878aSAndroid Build Coastguard Worker Measurement<size_t>& Measurements::GetBySize(size_t size) {
99*61c4878aSAndroid Build Coastguard Worker   PW_ASSERT(!by_size_.empty());
100*61c4878aSAndroid Build Coastguard Worker   auto iter = by_size_.upper_bound(size);
101*61c4878aSAndroid Build Coastguard Worker   if (iter != by_size_.begin()) {
102*61c4878aSAndroid Build Coastguard Worker     --iter;
103*61c4878aSAndroid Build Coastguard Worker   }
104*61c4878aSAndroid Build Coastguard Worker   return *iter;
105*61c4878aSAndroid Build Coastguard Worker }
106*61c4878aSAndroid Build Coastguard Worker 
107*61c4878aSAndroid Build Coastguard Worker // DefaultMeasurements methods
108*61c4878aSAndroid Build Coastguard Worker 
DefaultMeasurements(metric::Token name)109*61c4878aSAndroid Build Coastguard Worker DefaultMeasurements::DefaultMeasurements(metric::Token name)
110*61c4878aSAndroid Build Coastguard Worker     : Measurements(name) {
111*61c4878aSAndroid Build Coastguard Worker   for (auto& measurement : by_count_) {
112*61c4878aSAndroid Build Coastguard Worker     AddByCount(measurement);
113*61c4878aSAndroid Build Coastguard Worker   }
114*61c4878aSAndroid Build Coastguard Worker   for (auto& measurement : by_fragmentation_) {
115*61c4878aSAndroid Build Coastguard Worker     AddByFragmentation(measurement);
116*61c4878aSAndroid Build Coastguard Worker   }
117*61c4878aSAndroid Build Coastguard Worker   for (auto& measurement : by_size_) {
118*61c4878aSAndroid Build Coastguard Worker     AddBySize(measurement);
119*61c4878aSAndroid Build Coastguard Worker   }
120*61c4878aSAndroid Build Coastguard Worker }
121*61c4878aSAndroid Build Coastguard Worker 
122*61c4878aSAndroid Build Coastguard Worker }  // namespace pw::allocator
123