OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 Google Inc. All rights reserved. |
| 2 // |
| 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 |
| 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // |
| 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. |
| 14 |
| 15 #include "benchmark/reporter.h" |
| 16 #include "complexity.h" |
| 17 |
| 18 #include <algorithm> |
| 19 #include <cstdint> |
| 20 #include <iostream> |
| 21 #include <string> |
| 22 #include <tuple> |
| 23 #include <vector> |
| 24 |
| 25 #include "string_util.h" |
| 26 #include "timers.h" |
| 27 #include "check.h" |
| 28 |
| 29 // File format reference: http://edoceo.com/utilitas/csv-file-format. |
| 30 |
| 31 namespace benchmark { |
| 32 |
| 33 namespace { |
| 34 std::vector<std::string> elements = { |
| 35 "name", "iterations", "real_time", "cpu_time", |
| 36 "time_unit", "bytes_per_second", "items_per_second", "label", |
| 37 "error_occurred", "error_message"}; |
| 38 } |
| 39 |
| 40 bool CSVReporter::ReportContext(const Context& context) { |
| 41 PrintBasicContext(&GetErrorStream(), context); |
| 42 return true; |
| 43 } |
| 44 |
| 45 void CSVReporter::ReportRuns(const std::vector<Run> & reports) { |
| 46 std::ostream& Out = GetOutputStream(); |
| 47 |
| 48 if (!printed_header_) { |
| 49 // save the names of all the user counters |
| 50 for (const auto& run : reports) { |
| 51 for (const auto& cnt : run.counters) { |
| 52 user_counter_names_.insert(cnt.first); |
| 53 } |
| 54 } |
| 55 |
| 56 // print the header |
| 57 for (auto B = elements.begin(); B != elements.end();) { |
| 58 Out << *B++; |
| 59 if (B != elements.end()) Out << ","; |
| 60 } |
| 61 for (auto B = user_counter_names_.begin(); B != user_counter_names_.end();)
{ |
| 62 Out << ",\"" << *B++ << "\""; |
| 63 } |
| 64 Out << "\n"; |
| 65 |
| 66 printed_header_ = true; |
| 67 } else { |
| 68 // check that all the current counters are saved in the name set |
| 69 for (const auto& run : reports) { |
| 70 for (const auto& cnt : run.counters) { |
| 71 CHECK(user_counter_names_.find(cnt.first) != user_counter_names_.end()) |
| 72 << "All counters must be present in each run. " |
| 73 << "Counter named \"" << cnt.first |
| 74 << "\" was not in a run after being added to the header"; |
| 75 } |
| 76 } |
| 77 } |
| 78 |
| 79 // print results for each run |
| 80 for (const auto& run : reports) { |
| 81 PrintRunData(run); |
| 82 } |
| 83 |
| 84 } |
| 85 |
| 86 void CSVReporter::PrintRunData(const Run & run) { |
| 87 std::ostream& Out = GetOutputStream(); |
| 88 |
| 89 // Field with embedded double-quote characters must be doubled and the field |
| 90 // delimited with double-quotes. |
| 91 std::string name = run.benchmark_name; |
| 92 ReplaceAll(&name, "\"", "\"\""); |
| 93 Out << '"' << name << "\","; |
| 94 if (run.error_occurred) { |
| 95 Out << std::string(elements.size() - 3, ','); |
| 96 Out << "true,"; |
| 97 std::string msg = run.error_message; |
| 98 ReplaceAll(&msg, "\"", "\"\""); |
| 99 Out << '"' << msg << "\"\n"; |
| 100 return; |
| 101 } |
| 102 |
| 103 // Do not print iteration on bigO and RMS report |
| 104 if (!run.report_big_o && !run.report_rms) { |
| 105 Out << run.iterations; |
| 106 } |
| 107 Out << ","; |
| 108 |
| 109 Out << run.GetAdjustedRealTime() << ","; |
| 110 Out << run.GetAdjustedCPUTime() << ","; |
| 111 |
| 112 // Do not print timeLabel on bigO and RMS report |
| 113 if (run.report_big_o) { |
| 114 Out << GetBigOString(run.complexity); |
| 115 } else if (!run.report_rms) { |
| 116 Out << GetTimeUnitString(run.time_unit); |
| 117 } |
| 118 Out << ","; |
| 119 |
| 120 if (run.bytes_per_second > 0.0) { |
| 121 Out << run.bytes_per_second; |
| 122 } |
| 123 Out << ","; |
| 124 if (run.items_per_second > 0.0) { |
| 125 Out << run.items_per_second; |
| 126 } |
| 127 Out << ","; |
| 128 if (!run.report_label.empty()) { |
| 129 // Field with embedded double-quote characters must be doubled and the field |
| 130 // delimited with double-quotes. |
| 131 std::string label = run.report_label; |
| 132 ReplaceAll(&label, "\"", "\"\""); |
| 133 Out << "\"" << label << "\""; |
| 134 } |
| 135 Out << ",,"; // for error_occurred and error_message |
| 136 |
| 137 // Print user counters |
| 138 for (const auto &ucn : user_counter_names_) { |
| 139 auto it = run.counters.find(ucn); |
| 140 if(it == run.counters.end()) { |
| 141 Out << ","; |
| 142 } else { |
| 143 Out << "," << it->second; |
| 144 } |
| 145 } |
| 146 Out << '\n'; |
| 147 } |
| 148 |
| 149 } // end namespace benchmark |
OLD | NEW |