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 28// File format reference: http://edoceo.com/utilitas/csv-file-format. 29 30namespace benchmark { 31 32namespace { 33std::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"}; 37} 38 39bool CSVReporter::ReportContext(const Context& context) { 40 PrintBasicContext(&GetErrorStream(), context); 41 42 std::ostream& Out = GetOutputStream(); 43 for (auto B = elements.begin(); B != elements.end();) { 44 Out << *B++; 45 if (B != elements.end()) Out << ","; 46 } 47 Out << "\n"; 48 return true; 49} 50 51void CSVReporter::ReportRuns(const std::vector<Run>& reports) { 52 for (const auto& run : reports) PrintRunData(run); 53} 54 55void CSVReporter::PrintRunData(const Run& run) { 56 std::ostream& Out = GetOutputStream(); 57 58 // Field with embedded double-quote characters must be doubled and the field 59 // delimited with double-quotes. 60 std::string name = run.benchmark_name; 61 ReplaceAll(&name, "\"", "\"\""); 62 Out << '"' << name << "\","; 63 if (run.error_occurred) { 64 Out << std::string(elements.size() - 3, ','); 65 Out << "true,"; 66 std::string msg = run.error_message; 67 ReplaceAll(&msg, "\"", "\"\""); 68 Out << '"' << msg << "\"\n"; 69 return; 70 } 71 72 // Do not print iteration on bigO and RMS report 73 if (!run.report_big_o && !run.report_rms) { 74 Out << run.iterations; 75 } 76 Out << ","; 77 78 Out << run.GetAdjustedRealTime() << ","; 79 Out << run.GetAdjustedCPUTime() << ","; 80 81 // Do not print timeLabel on bigO and RMS report 82 if (run.report_big_o) { 83 Out << GetBigOString(run.complexity); 84 } else if (!run.report_rms) { 85 Out << GetTimeUnitString(run.time_unit); 86 } 87 Out << ","; 88 89 if (run.bytes_per_second > 0.0) { 90 Out << run.bytes_per_second; 91 } 92 Out << ","; 93 if (run.items_per_second > 0.0) { 94 Out << run.items_per_second; 95 } 96 Out << ","; 97 if (!run.report_label.empty()) { 98 // Field with embedded double-quote characters must be doubled and the field 99 // delimited with double-quotes. 100 std::string label = run.report_label; 101 ReplaceAll(&label, "\"", "\"\""); 102 Out << "\"" << label << "\""; 103 } 104 Out << ",,"; // for error_occurred and error_message 105 Out << '\n'; 106} 107 108} // end namespace benchmark 109