1 // Copyright 2015 Google Inc. All rights reserved.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
22 #include "benchmark/benchmark.h"
24 #include "complexity.h"
25 #include "string_util.h"
28 // File format reference: http://edoceo.com/utilitas/csv-file-format.
33 std::vector
<std::string
> elements
= {
34 "name", "iterations", "real_time", "cpu_time",
35 "time_unit", "bytes_per_second", "items_per_second", "label",
36 "error_occurred", "error_message"};
39 std::string
CsvEscape(const std::string
& s
) {
41 tmp
.reserve(s
.size() + 2);
52 return '"' + tmp
+ '"';
55 bool CSVReporter::ReportContext(const Context
& context
) {
56 PrintBasicContext(&GetErrorStream(), context
);
60 void CSVReporter::ReportRuns(const std::vector
<Run
>& reports
) {
61 std::ostream
& Out
= GetOutputStream();
63 if (!printed_header_
) {
64 // save the names of all the user counters
65 for (const auto& run
: reports
) {
66 for (const auto& cnt
: run
.counters
) {
67 if (cnt
.first
== "bytes_per_second" || cnt
.first
== "items_per_second")
69 user_counter_names_
.insert(cnt
.first
);
74 for (auto B
= elements
.begin(); B
!= elements
.end();) {
76 if (B
!= elements
.end()) Out
<< ",";
78 for (auto B
= user_counter_names_
.begin();
79 B
!= user_counter_names_
.end();) {
80 Out
<< ",\"" << *B
++ << "\"";
84 printed_header_
= true;
86 // check that all the current counters are saved in the name set
87 for (const auto& run
: reports
) {
88 for (const auto& cnt
: run
.counters
) {
89 if (cnt
.first
== "bytes_per_second" || cnt
.first
== "items_per_second")
91 BM_CHECK(user_counter_names_
.find(cnt
.first
) !=
92 user_counter_names_
.end())
93 << "All counters must be present in each run. "
94 << "Counter named \"" << cnt
.first
95 << "\" was not in a run after being added to the header";
100 // print results for each run
101 for (const auto& run
: reports
) {
106 void CSVReporter::PrintRunData(const Run
& run
) {
107 std::ostream
& Out
= GetOutputStream();
108 Out
<< CsvEscape(run
.benchmark_name()) << ",";
109 if (run
.error_occurred
) {
110 Out
<< std::string(elements
.size() - 3, ',');
112 Out
<< CsvEscape(run
.error_message
) << "\n";
116 // Do not print iteration on bigO and RMS report
117 if (!run
.report_big_o
&& !run
.report_rms
) {
118 Out
<< run
.iterations
;
122 Out
<< run
.GetAdjustedRealTime() << ",";
123 Out
<< run
.GetAdjustedCPUTime() << ",";
125 // Do not print timeLabel on bigO and RMS report
126 if (run
.report_big_o
) {
127 Out
<< GetBigOString(run
.complexity
);
128 } else if (!run
.report_rms
) {
129 Out
<< GetTimeUnitString(run
.time_unit
);
133 if (run
.counters
.find("bytes_per_second") != run
.counters
.end()) {
134 Out
<< run
.counters
.at("bytes_per_second");
137 if (run
.counters
.find("items_per_second") != run
.counters
.end()) {
138 Out
<< run
.counters
.at("items_per_second");
141 if (!run
.report_label
.empty()) {
142 Out
<< CsvEscape(run
.report_label
);
144 Out
<< ",,"; // for error_occurred and error_message
146 // Print user counters
147 for (const auto& ucn
: user_counter_names_
) {
148 auto it
= run
.counters
.find(ucn
);
149 if (it
== run
.counters
.end()) {
152 Out
<< "," << it
->second
;
158 } // end namespace benchmark