Index: apps/benchmark/measurements.cc |
diff --git a/apps/benchmark/measurements.cc b/apps/benchmark/measurements.cc |
index 96be8bfcb031f90cc8f618d315dfa9d7583bc282..46b058dc01bb5b5ef8addbbdfb0300e5d2290d48 100644 |
--- a/apps/benchmark/measurements.cc |
+++ b/apps/benchmark/measurements.cc |
@@ -4,10 +4,12 @@ |
#include "apps/benchmark/measurements.h" |
+#include <algorithm> |
+ |
namespace benchmark { |
namespace { |
-bool Match(const Event& event, const EventSpec& spec) { |
+static bool Match(const Event& event, const EventSpec& spec) { |
return event.name == spec.name && event.categories == spec.categories; |
} |
@@ -38,22 +40,42 @@ Measurements::Measurements(std::vector<Event> events, |
Measurements::~Measurements() {} |
-double Measurements::Measure(const Measurement& measurement) { |
+void Measurements::Measure(const Measurement& measurement, |
+ std::vector<double>* results) const { |
switch (measurement.type) { |
case MeasurementType::TIME_UNTIL: |
- return TimeUntil(measurement.target_event); |
+ results->push_back(TimeUntil(measurement.target_event)); |
+ break; |
case MeasurementType::TIME_BETWEEN: |
- return TimeBetween(measurement.target_event, measurement.second_event); |
+ results->push_back( |
+ TimeBetween(measurement.target_event, measurement.second_event)); |
+ break; |
case MeasurementType::AVG_DURATION: |
- return AvgDuration(measurement.target_event); |
+ results->push_back(AvgDuration(measurement.target_event)); |
+ break; |
+ case MeasurementType::MEDIAN_DURATION: { |
+ bool status = Percentiles(measurement.target_event, {0.5}, results); |
+ if (!status) { |
+ results->push_back(-1.0); |
+ } |
+ break; |
+ } |
+ case MeasurementType::DIST_DURATION: { |
+ bool status = |
+ Percentiles(measurement.target_event, {0.1, 0.5, 0.9}, results); |
+ if (!status) { |
+ results->push_back(-1.0); |
+ } |
+ break; |
+ } |
default: |
NOTREACHED(); |
- return double(); |
+ return; |
} |
} |
bool Measurements::EarliestOccurence(const EventSpec& event_spec, |
- base::TimeTicks* earliest) { |
+ base::TimeTicks* earliest) const { |
base::TimeTicks result; |
bool found = false; |
for (const Event& event : events_) { |
@@ -73,7 +95,7 @@ bool Measurements::EarliestOccurence(const EventSpec& event_spec, |
return true; |
} |
-double Measurements::TimeUntil(const EventSpec& event_spec) { |
+double Measurements::TimeUntil(const EventSpec& event_spec) const { |
base::TimeTicks earliest; |
if (!EarliestOccurence(event_spec, &earliest)) |
return -1.0; |
@@ -81,7 +103,7 @@ double Measurements::TimeUntil(const EventSpec& event_spec) { |
} |
double Measurements::TimeBetween(const EventSpec& first_event_spec, |
- const EventSpec& second_event_spec) { |
+ const EventSpec& second_event_spec) const { |
base::TimeTicks earliest_first_event; |
if (!EarliestOccurence(first_event_spec, &earliest_first_event)) |
return -1.0; |
@@ -93,7 +115,7 @@ double Measurements::TimeBetween(const EventSpec& first_event_spec, |
return (earliest_second_event - earliest_first_event).InMillisecondsF(); |
} |
-double Measurements::AvgDuration(const EventSpec& event_spec) { |
+double Measurements::AvgDuration(const EventSpec& event_spec) const { |
double sum = 0.0; |
int count = 0; |
for (const Event& event : events_) { |
@@ -112,4 +134,37 @@ double Measurements::AvgDuration(const EventSpec& event_spec) { |
return sum / count; |
} |
+bool Measurements::Percentiles(const EventSpec& event_spec, |
+ const std::vector<double>& percentiles, |
+ std::vector<double>* result) const { |
+ std::vector<double> durations; |
+ for (const Event& event : events_) { |
+ if (event.type != EventType::COMPLETE) |
+ continue; |
+ |
+ if (!Match(event, event_spec)) |
+ continue; |
+ |
+ durations.push_back(event.duration.InMillisecondsF()); |
+ } |
+ if (durations.size() == 0) { |
+ return false; |
+ } |
+ |
+ if (!std::is_sorted(percentiles.begin(), percentiles.end())) { |
+ LOG(ERROR) << "Requested percentiles should be sorted in increasing order"; |
+ return false; |
+ } |
+ |
+ for (double percentile : percentiles) { |
+ size_t index = |
+ static_cast<size_t>(static_cast<double>(durations.size()) * percentile); |
+ std::nth_element(durations.begin(), durations.begin() + index, |
+ durations.end()); |
+ result->push_back(durations[index]); |
+ } |
+ |
+ return true; |
+} |
+ |
} // namespace benchmark |