| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "garnet/bin/trace/results_output.h" |
| |
| #include <algorithm> |
| #include <limits> |
| #include <numeric> |
| |
| #include "src/lib/fxl/logging.h" |
| |
| namespace tracing { |
| |
| namespace { |
| |
| double Average(const std::vector<double>& samples) { |
| double sum = std::accumulate(std::cbegin(samples), std::cend(samples), 0.0); |
| return static_cast<double>(sum) / samples.size(); |
| } |
| |
| double Min(const std::vector<double>& samples) { |
| auto it = std::min_element(std::cbegin(samples), std::cend(samples)); |
| return *it; |
| } |
| |
| double Max(const std::vector<double>& samples) { |
| auto it = std::max_element(std::cbegin(samples), std::cend(samples)); |
| return *it; |
| } |
| |
| double StdDev(const std::vector<double>& samples, double average) { |
| double sum_of_squared_deltas = 0.0; |
| for (auto sample : samples) { |
| sum_of_squared_deltas += (sample - average) * (sample - average); |
| } |
| return std::sqrt(sum_of_squared_deltas / samples.size()); |
| } |
| |
| void OutputSamples(std::ostream& out, const std::vector<double>& values, |
| const std::string& unit) { |
| FXL_DCHECK(!values.empty()); |
| if (values.size() == 1) { |
| out << values.front() << unit; |
| return; |
| } |
| |
| double average = Average(values); |
| double std_dev = StdDev(values, average); |
| double min = Min(values); |
| double max = Max(values); |
| |
| out << "avg " << average << unit << " out of " << values.size() |
| << " samples. " |
| << "(std dev " << std_dev << ", min " << min << ", max " << max << ")"; |
| } |
| |
| } // namespace |
| |
| void OutputResults(std::ostream& out, |
| const std::vector<measure::Result>& results) { |
| out.precision(std::numeric_limits<double>::digits10); |
| |
| for (auto& result : results) { |
| out << result.label << " -> "; |
| if (result.values.empty()) { |
| out << " no results" << std::endl; |
| continue; |
| } |
| |
| if (!result.split_first) { |
| OutputSamples(out, result.values, result.unit); |
| out << std::endl; |
| continue; |
| } |
| |
| out << std::endl; |
| out << " sample 0: " << result.values.front() << result.unit << std::endl; |
| out << " samples 1 to " << result.values.size() - 1 << ": "; |
| std::vector<double> tail(result.values.begin() + 1, result.values.end()); |
| OutputSamples(out, tail, result.unit); |
| out << std::endl; |
| } |
| } |
| |
| } // namespace tracing |