123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- /*
- This file is part of cpp-ethereum.
- cpp-ethereum is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- cpp-ethereum is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
- */
- #include "Stats.h"
- #include <iterator>
- #include <numeric>
- #include <fstream>
- namespace dev
- {
- namespace test
- {
- Stats& Stats::get()
- {
- static Stats instance;
- return instance;
- }
- void Stats::suiteStarted(std::string const& _name)
- {
- m_currentSuite = _name;
- }
- void Stats::testStarted(std::string const& _name)
- {
- m_currentTest = _name;
- m_tp = clock::now();
- }
- void Stats::testFinished(int64_t _gasUsed)
- {
- m_stats.push_back({clock::now() - m_tp, _gasUsed, m_currentSuite + "/" + m_currentTest});
- }
- std::ostream& operator<<(std::ostream& out, Stats::clock::duration const& d)
- {
- return out << std::setw(10) << std::right << std::chrono::duration_cast<std::chrono::microseconds>(d).count() << " us";
- }
- Stats::~Stats()
- {
- if (m_stats.empty())
- return;
- std::sort(m_stats.begin(), m_stats.end(), [](Stats::Item const& a, Stats::Item const& b){
- return a.duration < b.duration;
- });
- auto& out = std::cout;
- auto itr = m_stats.begin();
- auto min = *itr;
- auto max = *m_stats.rbegin();
- std::advance(itr, m_stats.size() / 2);
- auto med = *itr;
- auto tot = std::accumulate(m_stats.begin(), m_stats.end(), clock::duration{}, [](clock::duration const& a, Stats::Item const& v)
- {
- return a + v.duration;
- });
- out << "\nSTATS:\n\n" << std::setfill(' ');
- if (Options::get().statsOutFile == "out")
- {
- for (auto&& s: m_stats)
- {
- auto usecs = std::chrono::duration_cast<std::chrono::microseconds>(s.duration).count();
- out << " " << std::setw(40) << std::left << s.name.substr(0, 40) << s.duration;
- if (s.gasUsed >= 0)
- {
- auto gasRate = uint64_t(double(s.gasUsed) * 1000 / usecs);
- out << "\t" << std::setw(10) << std::right << gasRate << " gas/ms\n";
- }
- else
- out << "\tOOG\n";
- }
- out << "\n";
- }
- else if (!Options::get().statsOutFile.empty())
- {
- // Output stats to file
- std::ofstream file{Options::get().statsOutFile};
- for (auto&& s: m_stats)
- {
- auto usecs = std::chrono::duration_cast<std::chrono::microseconds>(s.duration).count();
- file << s.name << "\t" << usecs;
- if (s.gasUsed >= 0)
- {
- auto gasRate = s.gasUsed / usecs;
- file << "\t" << gasRate << " gas/us\n";
- }
- else
- file << "\tOOG\n";
- }
- }
- out << " tot: " << tot << "\n"
- << " avg: " << (tot / m_stats.size()) << "\n\n"
- << " min: " << min.duration << " (" << min.name << ")\n"
- << " med: " << med.duration << " (" << med.name << ")\n"
- << " max: " << max.duration << " (" << max.name << ")\n";
- }
- }
- }
|