00001 #ifndef __HAYAI_CONSOLEOUTPUTTER 00002 #define __HAYAI_CONSOLEOUTPUTTER 00003 #include "hayai/hayai_outputter.hpp" 00004 #include "hayai/hayai_console.hpp" 00005 00006 00007 namespace hayai 00008 { 00010 00012 class ConsoleOutputter 00013 : public Outputter 00014 { 00015 public: 00017 00020 ConsoleOutputter(std::ostream& stream = std::cout) 00021 : _stream(stream) 00022 { 00023 00024 } 00025 00026 00027 virtual void Begin(const std::size_t& enabledCount, 00028 const std::size_t& disabledCount) 00029 { 00030 _stream << std::fixed; 00031 _stream << Console::TextGreen << "[==========]" 00032 << Console::TextDefault << " Running " 00033 << enabledCount 00034 << (enabledCount == 1 ? " benchmark." : " benchmarks"); 00035 00036 if (disabledCount) 00037 _stream << ", skipping " 00038 << disabledCount 00039 << (disabledCount == 1 ? 00040 " benchmark." : 00041 " benchmarks"); 00042 else 00043 { 00044 _stream << "."; 00045 } 00046 00047 _stream << std::endl; 00048 } 00049 00050 00051 virtual void End(const std::size_t& executedCount, 00052 const std::size_t& disabledCount) 00053 { 00054 _stream << Console::TextGreen << "[==========]" 00055 << Console::TextDefault << " Ran " << executedCount 00056 << (executedCount == 1 ? 00057 " benchmark." : 00058 " benchmarks"); 00059 00060 if (disabledCount) 00061 _stream << ", skipped " 00062 << disabledCount 00063 << (disabledCount == 1 ? 00064 " benchmark." : 00065 " benchmarks"); 00066 else 00067 { 00068 _stream << "."; 00069 } 00070 00071 _stream << std::endl; 00072 } 00073 00074 00075 inline void BeginOrSkipTest(const std::string& fixtureName, 00076 const std::string& testName, 00077 const TestParametersDescriptor& parameters, 00078 const std::size_t& runsCount, 00079 const std::size_t& iterationsCount, 00080 const bool skip) 00081 { 00082 if (skip) 00083 { 00084 _stream << Console::TextCyan << "[ DISABLED ]"; 00085 } 00086 else 00087 { 00088 _stream << Console::TextGreen << "[ RUN ]"; 00089 } 00090 00091 _stream << Console::TextYellow << " "; 00092 WriteTestNameToStream(_stream, fixtureName, testName, parameters); 00093 _stream << Console::TextDefault 00094 << " (" << runsCount 00095 << (runsCount == 1 ? " run, " : " runs, ") 00096 << iterationsCount 00097 << (iterationsCount == 1 ? 00098 " iteration per run)" : 00099 " iterations per run)") 00100 << std::endl; 00101 } 00102 00103 00104 virtual void BeginTest(const std::string& fixtureName, 00105 const std::string& testName, 00106 const TestParametersDescriptor& parameters, 00107 const std::size_t& runsCount, 00108 const std::size_t& iterationsCount) 00109 { 00110 BeginOrSkipTest(fixtureName, 00111 testName, 00112 parameters, 00113 runsCount, 00114 iterationsCount, 00115 false); 00116 } 00117 00118 00119 virtual void SkipDisabledTest( 00120 const std::string& fixtureName, 00121 const std::string& testName, 00122 const TestParametersDescriptor& parameters, 00123 const std::size_t& runsCount, 00124 const std::size_t& iterationsCount 00125 ) 00126 { 00127 BeginOrSkipTest(fixtureName, 00128 testName, 00129 parameters, 00130 runsCount, 00131 iterationsCount, 00132 true); 00133 } 00134 00135 00136 virtual void EndTest(const std::string& fixtureName, 00137 const std::string& testName, 00138 const TestParametersDescriptor& parameters, 00139 const TestResult& result) 00140 { 00141 #define PAD(x) _stream << std::setw(34) << x << std::endl; 00142 #define PAD_DEVIATION(description, \ 00143 deviated, \ 00144 average, \ 00145 unit) \ 00146 { \ 00147 double _d_ = \ 00148 double(deviated) - double(average); \ 00149 \ 00150 PAD(description << \ 00151 deviated << " " << unit << " (" << \ 00152 (deviated < average ? \ 00153 Console::TextRed : \ 00154 Console::TextGreen) << \ 00155 (deviated > average ? "+" : "") << \ 00156 _d_ << " " << unit << " / " << \ 00157 (deviated > average ? "+" : "") << \ 00158 (_d_ * 100.0 / average) << " %" << \ 00159 Console::TextDefault << ")"); \ 00160 } 00161 #define PAD_DEVIATION_INVERSE(description, \ 00162 deviated, \ 00163 average, \ 00164 unit) \ 00165 { \ 00166 double _d_ = \ 00167 double(deviated) - double(average); \ 00168 \ 00169 PAD(description << \ 00170 deviated << " " << unit << " (" << \ 00171 (deviated > average ? \ 00172 Console::TextRed : \ 00173 Console::TextGreen) << \ 00174 (deviated > average ? "+" : "") << \ 00175 _d_ << " " << unit << " / " << \ 00176 (deviated > average ? "+" : "") << \ 00177 (_d_ * 100.0 / average) << " %" << \ 00178 Console::TextDefault << ")"); \ 00179 } 00180 00181 _stream << Console::TextGreen << "[ DONE ]" 00182 << Console::TextYellow << " "; 00183 WriteTestNameToStream(_stream, fixtureName, testName, parameters); 00184 _stream << Console::TextDefault << " (" 00185 << std::setprecision(6) 00186 << (result.TimeTotal() / 1000000.0) << " ms)" 00187 << std::endl; 00188 00189 _stream << Console::TextBlue << "[ RUNS ] " 00190 << Console::TextDefault 00191 << " Average time: " 00192 << std::setprecision(3) 00193 << result.RunTimeAverage() / 1000.0 << " us" 00194 << std::endl; 00195 00196 PAD_DEVIATION_INVERSE("Fastest: ", 00197 (result.RunTimeMinimum() / 1000.0), 00198 (result.RunTimeAverage() / 1000.0), 00199 "us"); 00200 PAD_DEVIATION_INVERSE("Slowest: ", 00201 (result.RunTimeMaximum() / 1000.0), 00202 (result.RunTimeAverage() / 1000.0), 00203 "us"); 00204 00205 _stream << std::setprecision(5); 00206 00207 PAD(""); 00208 PAD("Average performance: " << 00209 result.RunsPerSecondAverage() << " runs/s"); 00210 PAD_DEVIATION("Best performance: ", 00211 result.RunsPerSecondMaximum(), 00212 result.RunsPerSecondAverage(), 00213 "runs/s"); 00214 PAD_DEVIATION("Worst performance: ", 00215 result.RunsPerSecondMinimum(), 00216 result.RunsPerSecondAverage(), 00217 "runs/s"); 00218 00219 _stream << Console::TextBlue << "[ITERATIONS] " 00220 << Console::TextDefault 00221 << std::setprecision(3) 00222 << " Average time: " 00223 << result.IterationTimeAverage() / 1000.0 << " us" 00224 << std::endl; 00225 00226 PAD_DEVIATION_INVERSE("Fastest: ", 00227 (result.IterationTimeMinimum() / 1000.0), 00228 (result.IterationTimeAverage() / 1000.0), 00229 "us"); 00230 PAD_DEVIATION_INVERSE("Slowest: ", 00231 (result.IterationTimeMaximum() / 1000.0), 00232 (result.IterationTimeAverage() / 1000.0), 00233 "us"); 00234 00235 _stream << std::setprecision(5); 00236 00237 PAD(""); 00238 PAD("Average performance: " << 00239 result.IterationsPerSecondAverage() << 00240 " iterations/s"); 00241 PAD_DEVIATION("Best performance: ", 00242 (result.IterationsPerSecondMaximum()), 00243 (result.IterationsPerSecondAverage()), 00244 "iterations/s"); 00245 PAD_DEVIATION("Worst performance: ", 00246 (result.IterationsPerSecondMinimum()), 00247 (result.IterationsPerSecondAverage()), 00248 "iterations/s"); 00249 00250 #undef PAD_DEVIATION_INVERSE 00251 #undef PAD_DEVIATION 00252 #undef PAD 00253 } 00254 00255 00256 std::ostream& _stream; 00257 }; 00258 } 00259 #endif