TODO: this does not include any file context when SHOWTIME_FILE thus rendering it useless - should we include the logging with the progress logging? that could also get rid of the broader locking
| 32 | // TODO: this does not include any file context when SHOWTIME_FILE thus rendering it useless - should we include the logging with the progress logging? |
| 33 | // that could also get rid of the broader locking |
| 34 | void TimerResults::showResults(size_t max_results, bool metrics) const |
| 35 | { |
| 36 | using dataElementType = std::pair<std::string, std::vector<std::chrono::milliseconds>>; |
| 37 | |
| 38 | std::vector<dataElementType> data; |
| 39 | { |
| 40 | std::lock_guard<std::mutex> l(mResultsSync); |
| 41 | |
| 42 | data.reserve(mResults.size()); |
| 43 | data.insert(data.begin(), mResults.cbegin(), mResults.cend()); |
| 44 | } |
| 45 | |
| 46 | const auto asSeconds = [](std::chrono::milliseconds ms) -> std::chrono::duration<double> { |
| 47 | return std::chrono::duration_cast<std::chrono::duration<double>>(ms); |
| 48 | }; |
| 49 | |
| 50 | const auto getSeconds = [&asSeconds](const std::vector<std::chrono::milliseconds>& results) -> std::chrono::duration<double> { |
| 51 | return std::accumulate(results.cbegin(), results.cend(), std::chrono::duration<double>{}, [&asSeconds](std::chrono::duration<double> secs, std::chrono::milliseconds duration) { |
| 52 | return secs + asSeconds(duration); |
| 53 | }); |
| 54 | }; |
| 55 | |
| 56 | std::sort(data.begin(), data.end(), [&getSeconds](const dataElementType& lhs, const dataElementType& rhs) -> bool { |
| 57 | return getSeconds(lhs.second) > getSeconds(rhs.second); |
| 58 | }); |
| 59 | |
| 60 | // lock the whole logging operation to avoid multiple threads printing their results at the same time |
| 61 | std::lock_guard<std::mutex> l(stdCoutLock); |
| 62 | |
| 63 | size_t ordinal = 1; // maybe it would be nice to have an ordinal in output later! |
| 64 | for (auto iter=data.cbegin(); iter!=data.cend(); ++iter) { |
| 65 | if (ordinal <= max_results) { |
| 66 | const double sec = getSeconds(iter->second).count(); |
| 67 | std::cout << iter->first << ": " << sec << "s"; |
| 68 | if (metrics) { |
| 69 | const double secAverage = sec / static_cast<double>(iter->second.size()); |
| 70 | const double secMin = asSeconds(*std::min_element(iter->second.cbegin(), iter->second.cend())).count(); |
| 71 | const double secMax = asSeconds(*std::max_element(iter->second.cbegin(), iter->second.cend())).count(); |
| 72 | std::cout << " (avg. " << secAverage << "s / min " << secMin << "s / max " << secMax << "s - " << iter->second.size() << " result(s))"; |
| 73 | } |
| 74 | std::cout << std::endl; |
| 75 | } |
| 76 | ++ordinal; |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | void TimerResults::addResults(const std::string& name, std::chrono::milliseconds duration) |
| 81 | { |