libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

csv_reporter.cc (4559B)


      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/benchmark.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 "check.h"
     26 #include "string_util.h"
     27 #include "timers.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 }  // namespace
     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         if (cnt.first == "bytes_per_second" || cnt.first == "items_per_second")
     53           continue;
     54         user_counter_names_.insert(cnt.first);
     55       }
     56     }
     57 
     58     // print the header
     59     for (auto B = elements.begin(); B != elements.end();) {
     60       Out << *B++;
     61       if (B != elements.end()) Out << ",";
     62     }
     63     for (auto B = user_counter_names_.begin();
     64          B != user_counter_names_.end();) {
     65       Out << ",\"" << *B++ << "\"";
     66     }
     67     Out << "\n";
     68 
     69     printed_header_ = true;
     70   } else {
     71     // check that all the current counters are saved in the name set
     72     for (const auto& run : reports) {
     73       for (const auto& cnt : run.counters) {
     74         if (cnt.first == "bytes_per_second" || cnt.first == "items_per_second")
     75           continue;
     76         CHECK(user_counter_names_.find(cnt.first) != user_counter_names_.end())
     77             << "All counters must be present in each run. "
     78             << "Counter named \"" << cnt.first
     79             << "\" was not in a run after being added to the header";
     80       }
     81     }
     82   }
     83 
     84   // print results for each run
     85   for (const auto& run : reports) {
     86     PrintRunData(run);
     87   }
     88 }
     89 
     90 void CSVReporter::PrintRunData(const Run& run) {
     91   std::ostream& Out = GetOutputStream();
     92 
     93   // Field with embedded double-quote characters must be doubled and the field
     94   // delimited with double-quotes.
     95   std::string name = run.benchmark_name();
     96   ReplaceAll(&name, "\"", "\"\"");
     97   Out << '"' << name << "\",";
     98   if (run.error_occurred) {
     99     Out << std::string(elements.size() - 3, ',');
    100     Out << "true,";
    101     std::string msg = run.error_message;
    102     ReplaceAll(&msg, "\"", "\"\"");
    103     Out << '"' << msg << "\"\n";
    104     return;
    105   }
    106 
    107   // Do not print iteration on bigO and RMS report
    108   if (!run.report_big_o && !run.report_rms) {
    109     Out << run.iterations;
    110   }
    111   Out << ",";
    112 
    113   Out << run.GetAdjustedRealTime() << ",";
    114   Out << run.GetAdjustedCPUTime() << ",";
    115 
    116   // Do not print timeLabel on bigO and RMS report
    117   if (run.report_big_o) {
    118     Out << GetBigOString(run.complexity);
    119   } else if (!run.report_rms) {
    120     Out << GetTimeUnitString(run.time_unit);
    121   }
    122   Out << ",";
    123 
    124   if (run.counters.find("bytes_per_second") != run.counters.end()) {
    125     Out << run.counters.at("bytes_per_second");
    126   }
    127   Out << ",";
    128   if (run.counters.find("items_per_second") != run.counters.end()) {
    129     Out << run.counters.at("items_per_second");
    130   }
    131   Out << ",";
    132   if (!run.report_label.empty()) {
    133     // Field with embedded double-quote characters must be doubled and the field
    134     // delimited with double-quotes.
    135     std::string label = run.report_label;
    136     ReplaceAll(&label, "\"", "\"\"");
    137     Out << "\"" << label << "\"";
    138   }
    139   Out << ",,";  // for error_occurred and error_message
    140 
    141   // Print user counters
    142   for (const auto& ucn : user_counter_names_) {
    143     auto it = run.counters.find(ucn);
    144     if (it == run.counters.end()) {
    145       Out << ",";
    146     } else {
    147       Out << "," << it->second;
    148     }
    149   }
    150   Out << '\n';
    151 }
    152 
    153 }  // end namespace benchmark