Stats.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. This file is part of cpp-ethereum.
  3. cpp-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. cpp-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include "Stats.h"
  15. #include <iterator>
  16. #include <numeric>
  17. #include <fstream>
  18. namespace dev
  19. {
  20. namespace test
  21. {
  22. Stats& Stats::get()
  23. {
  24. static Stats instance;
  25. return instance;
  26. }
  27. void Stats::suiteStarted(std::string const& _name)
  28. {
  29. m_currentSuite = _name;
  30. }
  31. void Stats::testStarted(std::string const& _name)
  32. {
  33. m_currentTest = _name;
  34. m_tp = clock::now();
  35. }
  36. void Stats::testFinished(int64_t _gasUsed)
  37. {
  38. m_stats.push_back({clock::now() - m_tp, _gasUsed, m_currentSuite + "/" + m_currentTest});
  39. }
  40. std::ostream& operator<<(std::ostream& out, Stats::clock::duration const& d)
  41. {
  42. return out << std::setw(10) << std::right << std::chrono::duration_cast<std::chrono::microseconds>(d).count() << " us";
  43. }
  44. Stats::~Stats()
  45. {
  46. if (m_stats.empty())
  47. return;
  48. std::sort(m_stats.begin(), m_stats.end(), [](Stats::Item const& a, Stats::Item const& b){
  49. return a.duration < b.duration;
  50. });
  51. auto& out = std::cout;
  52. auto itr = m_stats.begin();
  53. auto min = *itr;
  54. auto max = *m_stats.rbegin();
  55. std::advance(itr, m_stats.size() / 2);
  56. auto med = *itr;
  57. auto tot = std::accumulate(m_stats.begin(), m_stats.end(), clock::duration{}, [](clock::duration const& a, Stats::Item const& v)
  58. {
  59. return a + v.duration;
  60. });
  61. out << "\nSTATS:\n\n" << std::setfill(' ');
  62. if (Options::get().statsOutFile == "out")
  63. {
  64. for (auto&& s: m_stats)
  65. {
  66. auto usecs = std::chrono::duration_cast<std::chrono::microseconds>(s.duration).count();
  67. out << " " << std::setw(40) << std::left << s.name.substr(0, 40) << s.duration;
  68. if (s.gasUsed >= 0)
  69. {
  70. auto gasRate = uint64_t(double(s.gasUsed) * 1000 / usecs);
  71. out << "\t" << std::setw(10) << std::right << gasRate << " gas/ms\n";
  72. }
  73. else
  74. out << "\tOOG\n";
  75. }
  76. out << "\n";
  77. }
  78. else if (!Options::get().statsOutFile.empty())
  79. {
  80. // Output stats to file
  81. std::ofstream file{Options::get().statsOutFile};
  82. for (auto&& s: m_stats)
  83. {
  84. auto usecs = std::chrono::duration_cast<std::chrono::microseconds>(s.duration).count();
  85. file << s.name << "\t" << usecs;
  86. if (s.gasUsed >= 0)
  87. {
  88. auto gasRate = s.gasUsed / usecs;
  89. file << "\t" << gasRate << " gas/us\n";
  90. }
  91. else
  92. file << "\tOOG\n";
  93. }
  94. }
  95. out << " tot: " << tot << "\n"
  96. << " avg: " << (tot / m_stats.size()) << "\n\n"
  97. << " min: " << min.duration << " (" << min.name << ")\n"
  98. << " med: " << med.duration << " (" << med.name << ")\n"
  99. << " max: " << max.duration << " (" << max.name << ")\n";
  100. }
  101. }
  102. }