Home | History | Annotate | Download | only in src
      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 <cstdio>
     21 #include <iostream>
     22 #include <string>
     23 #include <tuple>
     24 #include <vector>
     25 
     26 #include "check.h"
     27 #include "colorprint.h"
     28 #include "commandlineflags.h"
     29 #include "internal_macros.h"
     30 #include "string_util.h"
     31 #include "timers.h"
     32 
     33 namespace benchmark {
     34 
     35 bool ConsoleReporter::ReportContext(const Context& context) {
     36   name_field_width_ = context.name_field_width;
     37 
     38   PrintBasicContext(&GetErrorStream(), context);
     39 
     40 #ifdef BENCHMARK_OS_WINDOWS
     41   if (color_output_ && &std::cout != &GetOutputStream()) {
     42     GetErrorStream()
     43         << "Color printing is only supported for stdout on windows."
     44            " Disabling color printing\n";
     45     color_output_ = false;
     46   }
     47 #endif
     48   std::string str =
     49       FormatString("%-*s %13s %13s %10s\n", static_cast<int>(name_field_width_),
     50                    "Benchmark", "Time", "CPU", "Iterations");
     51   GetOutputStream() << str << std::string(str.length() - 1, '-') << "\n";
     52 
     53   return true;
     54 }
     55 
     56 void ConsoleReporter::ReportRuns(const std::vector<Run>& reports) {
     57   for (const auto& run : reports) PrintRunData(run);
     58 }
     59 
     60 static void IgnoreColorPrint(std::ostream& out, LogColor, const char* fmt,
     61                              ...) {
     62   va_list args;
     63   va_start(args, fmt);
     64   out << FormatString(fmt, args);
     65   va_end(args);
     66 }
     67 
     68 void ConsoleReporter::PrintRunData(const Run& result) {
     69   typedef void(PrinterFn)(std::ostream&, LogColor, const char*, ...);
     70   auto& Out = GetOutputStream();
     71   PrinterFn* printer =
     72       color_output_ ? (PrinterFn*)ColorPrintf : IgnoreColorPrint;
     73   auto name_color =
     74       (result.report_big_o || result.report_rms) ? COLOR_BLUE : COLOR_GREEN;
     75   printer(Out, name_color, "%-*s ", name_field_width_,
     76           result.benchmark_name.c_str());
     77 
     78   if (result.error_occurred) {
     79     printer(Out, COLOR_RED, "ERROR OCCURRED: \'%s\'",
     80             result.error_message.c_str());
     81     printer(Out, COLOR_DEFAULT, "\n");
     82     return;
     83   }
     84   // Format bytes per second
     85   std::string rate;
     86   if (result.bytes_per_second > 0) {
     87     rate = StrCat(" ", HumanReadableNumber(result.bytes_per_second), "B/s");
     88   }
     89 
     90   // Format items per second
     91   std::string items;
     92   if (result.items_per_second > 0) {
     93     items =
     94         StrCat(" ", HumanReadableNumber(result.items_per_second), " items/s");
     95   }
     96 
     97   const double real_time = result.GetAdjustedRealTime();
     98   const double cpu_time = result.GetAdjustedCPUTime();
     99 
    100   if (result.report_big_o) {
    101     std::string big_o = GetBigOString(result.complexity);
    102     printer(Out, COLOR_YELLOW, "%10.2f %s %10.2f %s ", real_time, big_o.c_str(),
    103             cpu_time, big_o.c_str());
    104   } else if (result.report_rms) {
    105     printer(Out, COLOR_YELLOW, "%10.0f %% %10.0f %% ", real_time * 100,
    106             cpu_time * 100);
    107   } else {
    108     const char* timeLabel = GetTimeUnitString(result.time_unit);
    109     printer(Out, COLOR_YELLOW, "%10.0f %s %10.0f %s ", real_time, timeLabel,
    110             cpu_time, timeLabel);
    111   }
    112 
    113   if (!result.report_big_o && !result.report_rms) {
    114     printer(Out, COLOR_CYAN, "%10lld", result.iterations);
    115   }
    116 
    117   if (!rate.empty()) {
    118     printer(Out, COLOR_DEFAULT, " %*s", 13, rate.c_str());
    119   }
    120 
    121   if (!items.empty()) {
    122     printer(Out, COLOR_DEFAULT, " %*s", 18, items.c_str());
    123   }
    124 
    125   if (!result.report_label.empty()) {
    126     printer(Out, COLOR_DEFAULT, " %s", result.report_label.c_str());
    127   }
    128 
    129   printer(Out, COLOR_DEFAULT, "\n");
    130 }
    131 
    132 }  // end namespace benchmark
    133