diff --git a/aarbology2/src/aarbology.cpp b/aarbology2/src/aarbology.cpp index 673a0a8d8e370702bd8847c3f2cc85dbc3b8dcb5..11bbca4e12c2984f65899d0aee0ba39768904fbf 100644 --- a/aarbology2/src/aarbology.cpp +++ b/aarbology2/src/aarbology.cpp @@ -15,6 +15,7 @@ #include <arbology/exact/ExactSubtreeMatch.h> #include <arbology/exact/ExactSubtreeMatchingAutomaton.h> +#include <chrono> int main(int argc, char* argv[]) { try { @@ -34,6 +35,12 @@ int main(int argc, char* argv[]) { TCLAP::MultiArg<std::string> pattern( "p", "pattern", "Pattern tree from file", false, "file"); cmd.add( pattern ); + TCLAP::SwitchArg measure( "m", "measure", "Measure times", false); + cmd.add( measure ); + + TCLAP::SwitchArg verbose( "v", "verbose", "Be verbose", false); + cmd.add( verbose ); + cmd.parse(argc,argv); int needPattern = 0; @@ -45,6 +52,8 @@ int main(int argc, char* argv[]) { } else { } + std::chrono::measurements::start("Overal", std::chrono::measurements::Type::OVERALL); + std::chrono::measurements::start("Input read", std::chrono::measurements::Type::AUXILARY); std::deque<std::deque<sax::Token>> subjectTokens; if(subject.isSet()) { for(const std::string& fileName : subject.getValue()) { @@ -82,18 +91,39 @@ int main(int argc, char* argv[]) { if( algorithm.getValue() == "exactSubtreeMatch") { tree::Tree subject = alib::XmlDataFactory::fromTokens<tree::Tree>(subjectTokens.front()); tree::Tree pattern = alib::XmlDataFactory::fromTokens<tree::Tree>(patternTokens.front()); + + std::chrono::measurements::end(); + std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::FINALIZE); + std::set<unsigned> res = arbology::exact::ExactSubtreeMatch::match(subject, pattern); + + std::chrono::measurements::end(); + std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + alib::XmlDataFactory::toStdout(res); - return 0; } else if( algorithm.getValue() == "exactSubtreeMatchingAutomaton") { tree::Tree pattern = alib::XmlDataFactory::fromTokens<tree::Tree>(patternTokens.front()); + + std::chrono::measurements::end(); + std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::FINALIZE); + automaton::Automaton res = arbology::exact::ExactSubtreeMatchingAutomaton::construct(pattern); + + std::chrono::measurements::end(); + std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + alib::XmlDataFactory::toStdout(res); - return 0; } else { throw exception::AlibException( "Invalid algorithm" ); return 1; } + + std::chrono::measurements::end(); + std::chrono::measurements::end(); + + if(measure.getValue()) std::clog << std::chrono::measurements::results() << std::endl; + + return 0; } catch( const exception::AlibException & exception ) { alib::XmlDataFactory::toStdout( exception ); return 1; diff --git a/aecho2/src/aecho.cpp b/aecho2/src/aecho.cpp index 6aa088f0ab6e145e4236d20675989114374bcd09..128cfe1bc5cd0528a512e7c7ddd9071bea8e6381 100644 --- a/aecho2/src/aecho.cpp +++ b/aecho2/src/aecho.cpp @@ -41,17 +41,20 @@ int main(int argc, char** argv) { sax::SaxParseInterface::parseStdin(tokens); } - std::chrono::measurements measurements; - measurements.start("Overal", std::chrono::measurements::Type::OVERALL); - measurements.start("XML Parse", std::chrono::measurements::Type::INIT); + std::chrono::measurements::start("Overal", std::chrono::measurements::Type::OVERALL); + std::chrono::measurements::start("Input read", std::chrono::measurements::Type::AUXILARY); + alib::Object object = alib::XmlDataFactory::fromTokens<alib::Object>(tokens); - measurements.end(); - measurements.start("XML Compose", std::chrono::measurements::Type::FINALIZE); + + std::chrono::measurements::end(); + std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + alib::XmlDataFactory::toStdout(object); - measurements.end(); - measurements.end(); - if(measure.getValue()) std::clog << measurements.results() << std::endl; + std::chrono::measurements::end(); + std::chrono::measurements::end(); + + if(measure.getValue()) std::clog << std::chrono::measurements::results() << std::endl; return 0; } catch(const exception::AlibException& exception) { diff --git a/alib2data/src/factory/XmlDataFactory.hpp b/alib2data/src/factory/XmlDataFactory.hpp index d82d0e8b9b5903da1812bf0632651c39c131926f..a76acd00626a2a01aa1d2c8a6ebbd79ffcde1cfa 100644 --- a/alib2data/src/factory/XmlDataFactory.hpp +++ b/alib2data/src/factory/XmlDataFactory.hpp @@ -15,6 +15,7 @@ #include "../sax/SaxParseInterface.h" #include "../sax/SaxComposeInterface.h" #include "../XmlApi.hpp" +#include <chrono> namespace alib { @@ -80,7 +81,9 @@ public: if(alib::xmlApi<exception::AlibException>::first(tokens)) throw alib::xmlApi<exception::AlibException>::parse(tokens); + std::chrono::measurements::start("XML Parser", std::chrono::measurements::Type::INIT); T res = alib::xmlApi<T>::parse(tokens); + std::chrono::measurements::end(); if(tokens.size() != 0) throw exception::AlibException("Unexpeted tokens at the end of the xml"); return res; } @@ -147,7 +150,9 @@ public: template<class T> static std::deque<sax::Token> toTokens(const T& data) { std::deque<sax::Token> res; + std::chrono::measurements::start("XML Composer", std::chrono::measurements::Type::FINALIZE); alib::xmlApi<T>::compose(res, data); + std::chrono::measurements::end(); return res; } diff --git a/alib2data/src/sax/SaxComposeInterface.cpp b/alib2data/src/sax/SaxComposeInterface.cpp index cdcb51e3f8b9f9f327f64d8e21f6de04c52c84c2..2400cd45e277875a0ef1381a2a2d718a7e6a7c7a 100644 --- a/alib2data/src/sax/SaxComposeInterface.cpp +++ b/alib2data/src/sax/SaxComposeInterface.cpp @@ -13,6 +13,7 @@ #include <sstream> #include <deque> #include "ComposerException.h" +#include <chrono> namespace sax { @@ -51,6 +52,7 @@ void SaxComposeInterface::printStream(std::ostream& out, const std::deque<Token> } void SaxComposeInterface::xmlSAXUserPrint(xmlTextWriterPtr writer, const std::deque<Token>& in) { + std::chrono::measurements::start("Sax Composer", std::chrono::measurements::Type::FINALIZE); xmlTextWriterStartDocument(writer, NULL, NULL, NULL); #ifdef DEBUG std::deque<Token> stack; @@ -93,6 +95,7 @@ void SaxComposeInterface::xmlSAXUserPrint(xmlTextWriterPtr writer, const std::de } } xmlTextWriterEndDocument(writer); + std::chrono::measurements::end(); } } /* namespace sax */ diff --git a/alib2data/src/sax/SaxParseInterface.cpp b/alib2data/src/sax/SaxParseInterface.cpp index 7f08b2f2cc850d3a13eb81d46b72b41094534fa9..3060f72a5e5c56492103392b74b92cc13e6dc678 100644 --- a/alib2data/src/sax/SaxParseInterface.cpp +++ b/alib2data/src/sax/SaxParseInterface.cpp @@ -13,6 +13,7 @@ #include <iostream> #include <algorithm> #include "../exception/AlibException.h" +#include <chrono> namespace sax { @@ -20,8 +21,10 @@ void SaxParseInterface::initSAXHandler(xmlSAXHandler& handler) { memset(&handler, 0, sizeof(handler)); handler.initialized = XML_SAX2_MAGIC; + handler.startDocument = &sax::SaxParseInterface::startDocument; handler.startElement = &sax::SaxParseInterface::startElement; handler.endElement = &sax::SaxParseInterface::endElement; + handler.endDocument = &sax::SaxParseInterface::endDocument; handler.characters = &sax::SaxParseInterface::characters; } @@ -65,6 +68,10 @@ void SaxParseInterface::characters(void * userData, const xmlChar * ch, int len) if(! std::all_of(tmp.begin(), tmp.end(), isspace)) out.emplace_back(std::move(tmp), Token::TokenType::CHARACTER); } +void SaxParseInterface::startDocument(void *) { + std::chrono::measurements::start("Sax Parser", std::chrono::measurements::Type::INIT); +} + void SaxParseInterface::startElement(void* userData, const xmlChar* name, const xmlChar** attrs) { std::deque<Token> &out = *((std::deque<Token>*) userData); out.emplace_back(Token((const char*) name, Token::TokenType::START_ELEMENT)); @@ -84,4 +91,8 @@ void SaxParseInterface::endElement(void * userData, const xmlChar * name) { out.emplace_back((const char*) name, Token::TokenType::END_ELEMENT); } +void SaxParseInterface::endDocument(void *) { + std::chrono::measurements::end(); +} + } /* namespace sax */ diff --git a/alib2data/src/sax/SaxParseInterface.h b/alib2data/src/sax/SaxParseInterface.h index 345b89fed7d1475eb8ae4e43eac2ba0df5e24153..4f08bff4a6129f2d4c6826fbb691fa1f0a1f89db 100644 --- a/alib2data/src/sax/SaxParseInterface.h +++ b/alib2data/src/sax/SaxParseInterface.h @@ -33,6 +33,11 @@ protected: */ static void characters(void * userData, const xmlChar * ch, int len); + /** + * Callback method called when start of the document is read. + */ + static void startDocument(void * userData); + /** * Callback method called when start of the tag is read. * @param userData contains list of parsed tokens @@ -48,6 +53,11 @@ protected: */ static void endElement(void * userData, const xmlChar * name); + /** + * Callback method called when end of the document is read. + */ + static void endDocument(void * userData); + public: /** * Parses the string containing XML. diff --git a/alib2std/src/chrono b/alib2std/src/chrono index bf4e51f27b73eea380e37ee57b802f2d444dc9ab..551a83d5427954d0a5bd8d5b12ed951cb0d3775f 100644 --- a/alib2std/src/chrono +++ b/alib2std/src/chrono @@ -2,6 +2,12 @@ #define __CHRONO_HEADER_WRAPPER_ #include <bits/../chrono> +#include "vector" +#include "set" +#include "map" +#include "deque" +#include "exception" +#include "tuple" #include "extensions/chrono.hpp" #endif /* __CHRONO_HEADER_WRAPPER_ */ diff --git a/alib2std/src/extensions/chrono.cpp b/alib2std/src/extensions/chrono.cpp new file mode 100644 index 0000000000000000000000000000000000000000..abc45638009c6506191853cfa3de81788eff8eb6 --- /dev/null +++ b/alib2std/src/extensions/chrono.cpp @@ -0,0 +1,136 @@ +/* + * chrono.cpp + * + * Created on: Apr 1, 2013 + * Author: Jan Travnicek + */ + +#include "../chrono" + +namespace std { + +namespace chrono { + +measurements measurements::INSTANCE; + +measurements::Format measurements::Format::LIST = { 0 }; +measurements::Format measurements::Format::TREE = { 1 }; + +measurements::Filter measurements::Filter::ALL = { true, ~0u }; +measurements::Filter measurements::Filter::NONE = { false, ~0u }; +measurements::Filter measurements::Filter::OVERALL = { true, measurements::Type::OVERALL }; +measurements::Filter measurements::Filter::NO_OVERALL = { false, measurements::Type::OVERALL }; +measurements::Filter measurements::Filter::INIT = { true, measurements::Type::INIT }; +measurements::Filter measurements::Filter::NO_INIT = { false, measurements::Type::INIT }; +measurements::Filter measurements::Filter::FINALIZE = { true, measurements::Type::FINALIZE }; +measurements::Filter measurements::Filter::NO_FINALIZE = { false, measurements::Type::FINALIZE }; +measurements::Filter measurements::Filter::MAIN = { true, measurements::Type::MAIN }; +measurements::Filter measurements::Filter::NO_MAIN = { false, measurements::Type::MAIN }; +measurements::Filter measurements::Filter::AUXILARY = { true, measurements::Type::AUXILARY }; +measurements::Filter measurements::Filter::NO_AUXILARY = { false, measurements::Type::AUXILARY }; + +const int measurements::measurements_format_index = std::ios::xalloc(); +const int measurements::measurements_filter_index = std::ios::xalloc(); + +void printAsList(std::ostream& out, const measurements::Results& data, unsigned index) { + const unsigned filter = out.iword(measurements::measurements_filter_index); + + if(data.results.size() - 1 != index) out << ", "; + if((std::get<1>(data[index]) & filter) == 0) out << data[index]; + for(unsigned idx : std::get<4>(data[index])) { + printAsList(out, data, idx); + } +} + +void subtreeSizes(std::ostream& out, const measurements::Results& data, unsigned index, std::map<unsigned, unsigned>& res) { + res[index] = 0; + + const unsigned filter = out.iword(measurements::measurements_filter_index); + if((std::get<1>(data[index]) & filter) == 0) res[index] += 1; + + for(unsigned idx : std::get<4>(data[index])) { + subtreeSizes(out, data, idx, res); + res[index] += res[idx]; + } +} + +void printAsTree(std::ostream& out, std::string& prefix, map<unsigned, unsigned>& indexToSize, const measurements::Results& data, unsigned index, bool last) { + const unsigned filter = out.iword(measurements::measurements_filter_index); + if((std::get<1>(data[index]) & filter) == 0) { + if(last) prefix[prefix.size() - 2] = '\\'; + if(indexToSize[index] != 1) prefix += "+"; + + out << prefix << data[index] << std::endl; + + if(indexToSize[index] == 1) prefix += "-"; + prefix += "-"; + if(last) prefix[prefix.size() - 4] = ' '; + prefix[prefix.size() - 3] = ' '; + prefix[prefix.size() - 2] = '|'; + + unsigned size = std::get<4>(data[index]).size(); + for(unsigned idx : std::get<4>(data[index])) { + printAsTree(out, prefix, indexToSize, data, idx, size == 1); + size--; + } + prefix[prefix.size() - 3] = '-'; + + prefix.pop_back(); + prefix.pop_back(); + } else { + unsigned size = std::get<4>(data[index]).size(); + for(unsigned idx : std::get<4>(data[index])) { + printAsTree(out, prefix, indexToSize, data, idx, size == 1 && last); + size --; + } + } +} + +std::ostream& operator<<(std::ostream& out, const measurements::Results& data) { + const unsigned format = out.iword(measurements::measurements_format_index); + + unsigned index = data.results.size() - 1; + if(format == measurements::Format::LIST.type) { + printAsList(out, data, index); + } else { + std::string prefix = "|-"; + std::map<unsigned, unsigned> indexToSize; + subtreeSizes(out, data, index, indexToSize); + + printAsTree(out, prefix, indexToSize, data, index, true); + } + +// out << format << " " << filter << " " << data.results; + return out; +} + +std::ostream& operator<<(std::ostream& out, microseconds time) { + out << time.count() << "ms"; + return out; +} + +std::ostream& operator<<(std::ostream& out, measurements::Type type) { + switch(type) { + case measurements::Type::INIT: + out << "INIT"; + break; + case measurements::Type::FINALIZE: + out << "FINALIZE"; + break; + case measurements::Type::MAIN: + out << "MAIN"; + break; + case measurements::Type::AUXILARY: + out << "AUXILARY"; + break; + case measurements::Type::OVERALL: + out << "OVERALL"; + break; + } + return out; +} + +} /* namespace chrono */ + +} /* namespace std */ + diff --git a/alib2std/src/extensions/chrono.hpp b/alib2std/src/extensions/chrono.hpp index 158284e9a706ae4a62cb587942f0dc7e96cd3964..5c8660c39a05d2337f6c8dd899c25d8f5b39a042 100644 --- a/alib2std/src/extensions/chrono.hpp +++ b/alib2std/src/extensions/chrono.hpp @@ -33,64 +33,103 @@ public: class measurements { public: - enum class Type { - OVERALL, - INIT, - FINALIZE, - MAIN, - AUXILARY + enum Type { + OVERALL = 1, + INIT = 2, + FINALIZE = 4, + MAIN = 8, + AUXILARY = 16 }; + struct Format { + unsigned type; + + static Format LIST; + static Format TREE; + }; + + struct Filter { + bool set; + unsigned val; + + static Filter ALL; + static Filter NONE; + static Filter OVERALL; + static Filter NO_OVERALL; + static Filter INIT; + static Filter NO_INIT; + static Filter FINALIZE; + static Filter NO_FINALIZE; + static Filter MAIN; + static Filter NO_MAIN; + static Filter AUXILARY; + static Filter NO_AUXILARY; + + }; + + struct Results { + const std::vector<std::tuple<std::string, measurements::Type, microseconds, microseconds, std::set<unsigned>>>& results; + + const std::tuple<std::string, measurements::Type, microseconds, microseconds, std::set<unsigned>>& operator[](int idx) const { + return results[idx]; + } + }; + + static const int measurements_format_index; + static const int measurements_filter_index; + private: - std::vector<std::tuple<std::string, measurements::Type, microseconds, microseconds>> measurements_vector; // name, type, complete duration, real duration - std::deque<std::tuple<std::string, measurements::Type, time_point<system_clock>, microseconds>> measurements_stack; // name, type, start, sub measurements duration + std::vector<std::tuple<std::string, measurements::Type, microseconds, microseconds, std::set<unsigned>>> measurements_vector; // name, type, complete duration, real duration + std::deque<std::tuple<std::string, measurements::Type, time_point<system_clock>, microseconds, std::set<unsigned>>> measurements_stack; // name, type, start, sub measurements duration + + static measurements INSTANCE; public: - void start(std::string name, measurements::Type type) { - measurements_stack.emplace_back(std::move(name), type, system_clock::now(), microseconds(0)); + static void start(std::string name, measurements::Type type) { + INSTANCE.measurements_stack.emplace_back(std::move(name), type, system_clock::now(), microseconds(0), std::set<unsigned>{}); } - void end() { - if(measurements_stack.empty()) throw std::logic_error("no measurement started"); + static void end() { + if(INSTANCE.measurements_stack.empty()) throw std::logic_error("no measurement started"); - std::tuple<std::string, measurements::Type, time_point<system_clock>, microseconds> current = std::move(measurements_stack.back()); - measurements_stack.pop_back(); + std::tuple<std::string, measurements::Type, time_point<system_clock>, microseconds, std::set<unsigned>> current = std::move(INSTANCE.measurements_stack.back()); + INSTANCE.measurements_stack.pop_back(); microseconds dur = duration_cast<microseconds>(system_clock::now() - std::get<2>(current)); - measurements_vector.emplace_back(std::move(std::get<0>(current)), std::get<1>(current), dur, dur - std::get<3>(current)); - if(!measurements_stack.empty()) - std::get<3>(measurements_stack.back()) = std::get<3>(measurements_stack.back()) + std::get<2>(measurements_vector.back()); + unsigned index = INSTANCE.measurements_vector.size(); + INSTANCE.measurements_vector.emplace_back(std::move(std::get<0>(current)), std::get<1>(current), dur, dur - std::get<3>(current), std::get<4>(current)); + if(!INSTANCE.measurements_stack.empty()) { + std::get<3>(INSTANCE.measurements_stack.back()) += std::get<2>(INSTANCE.measurements_vector.back()); + std::get<4>(INSTANCE.measurements_stack.back()).insert(index); + } } - const decltype(measurements_vector)& results() const { - return measurements_vector; + static Results results() { + return { INSTANCE.measurements_vector }; } }; -std::ostream& operator<<(std::ostream& out, microseconds time) { - out << time.count() << "ms"; +std::ostream& operator<<(std::ostream& out, const measurements::Results& data); + +std::ostream& operator<<(std::ostream& out, microseconds time); + +std::ostream& operator<<(std::ostream& out, measurements::Type type); + +template<typename _CharT, typename _Traits> +inline basic_ostream<_CharT, _Traits>& operator <<( basic_ostream<_CharT, _Traits>& x, measurements::Format f) { + x.iword(measurements::measurements_format_index) = f.type; + return x; } -std::ostream& operator<<(std::ostream& out, measurements::Type type) { - switch(type) { - case measurements::Type::INIT: - out << "INIT"; - break; - case measurements::Type::FINALIZE: - out << "FINALIZE"; - break; - case measurements::Type::MAIN: - out << "MAIN"; - break; - case measurements::Type::AUXILARY: - out << "AUXILARY"; - break; - case measurements::Type::OVERALL: - out << "OVERALL"; - break; - } +template<typename _CharT, typename _Traits> +inline basic_ostream<_CharT, _Traits>& operator <<( basic_ostream<_CharT, _Traits>& x, measurements::Filter f) { + if(f.set) + x.iword(measurements::measurements_filter_index) &= ~f.val; + else + x.iword(measurements::measurements_filter_index) |= f.val; + return x; } } /* namespace chrono */ diff --git a/alib2std/test-src/extensions/ChronoTest.cpp b/alib2std/test-src/extensions/ChronoTest.cpp index fdaedd4fce53b93a675dbc2d0176a1bc7d570808..7fef5eaeab8f6f97de94c7425bccacc6e600325d 100644 --- a/alib2std/test-src/extensions/ChronoTest.cpp +++ b/alib2std/test-src/extensions/ChronoTest.cpp @@ -25,28 +25,44 @@ void ChronoTest::testChrono1() { void ChronoTest::testChrono2() { std::chrono::measurements meas; - meas.start("global", std::chrono::measurements::Type::MAIN); + meas.start("global", std::chrono::measurements::Type::OVERALL); - meas.start("init", std::chrono::measurements::Type::INIT); + std::chrono::measurements::start("init", std::chrono::measurements::Type::INIT); std::this_thread::sleep_for(std::chrono::milliseconds(100)); - meas.end(); + std::chrono::measurements::end(); - meas.start("main", std::chrono::measurements::Type::MAIN); + std::chrono::measurements::start("main", std::chrono::measurements::Type::MAIN); std::this_thread::sleep_for(std::chrono::milliseconds(20)); - meas.start("aux", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::start("aux", std::chrono::measurements::Type::AUXILARY); std::this_thread::sleep_for(std::chrono::milliseconds(40)); - meas.end(); + std::chrono::measurements::end(); std::this_thread::sleep_for(std::chrono::milliseconds(80)); - meas.end(); + std::chrono::measurements::start("aux", std::chrono::measurements::Type::AUXILARY); + std::this_thread::sleep_for(std::chrono::milliseconds(40)); + std::chrono::measurements::end(); + std::this_thread::sleep_for(std::chrono::milliseconds(80)); + std::chrono::measurements::end(); - meas.start("fin", std::chrono::measurements::Type::FINALIZE); + std::chrono::measurements::start("fin", std::chrono::measurements::Type::FINALIZE); std::this_thread::sleep_for(std::chrono::milliseconds(30)); - meas.end(); - meas.end(); + std::chrono::measurements::start("aux", std::chrono::measurements::Type::AUXILARY); + std::this_thread::sleep_for(std::chrono::milliseconds(40)); + std::chrono::measurements::end(); + std::this_thread::sleep_for(std::chrono::milliseconds(80)); + std::chrono::measurements::end(); + std::chrono::measurements::end(); + + std::cout << "Default print" << std::endl << std::chrono::measurements::results() << std::endl; - std::cout << meas.results() << std::endl; + CPPUNIT_ASSERT((std::get<3>(std::chrono::measurements::results()[1]) + std::get<3>(std::chrono::measurements::results()[2]) + std::get<3>(std::chrono::measurements::results()[3]))/1000 == std::get<2>(std::chrono::measurements::results()[3])/1000); + CPPUNIT_ASSERT((std::get<3>(std::chrono::measurements::results()[0]) + std::get<3>(std::chrono::measurements::results()[1]) + std::get<3>(std::chrono::measurements::results()[2]) + std::get<3>(std::chrono::measurements::results()[3]) + std::get<3>(std::chrono::measurements::results()[4]) + std::get<3>(std::chrono::measurements::results()[5]))/1000 == std::get<2>(std::chrono::measurements::results()[6])/1000); - CPPUNIT_ASSERT((std::get<3>(meas.results()[1]) + std::get<3>(meas.results()[2]))/1000 == std::get<2>(meas.results()[2])/1000); - CPPUNIT_ASSERT((std::get<3>(meas.results()[0]) + std::get<3>(meas.results()[1]) + std::get<3>(meas.results()[2]) + std::get<3>(meas.results()[3]))/1000 == std::get<2>(meas.results()[4])/1000); + std::cout << "Tree print" << std::endl << std::chrono::measurements::Format::TREE << std::chrono::measurements::results() << std::endl; + std::cout << "Tree print none" << std::endl << std::chrono::measurements::Format::TREE << std::chrono::measurements::Filter::NONE << std::chrono::measurements::results() << std::endl; + std::cout << "Tree print all - main" << std::endl << std::chrono::measurements::Format::TREE << std::chrono::measurements::Filter::ALL << std::chrono::measurements::Filter::NO_MAIN << std::chrono::measurements::results() << std::endl; + std::cout << "Tree print all - overall" << std::endl << std::chrono::measurements::Format::TREE << std::chrono::measurements::Filter::ALL << std::chrono::measurements::Filter::NO_OVERALL << std::chrono::measurements::results() << std::endl; + std::cout << "Tree print all - overall, main" << std::endl << std::chrono::measurements::Format::TREE << std::chrono::measurements::Filter::ALL << std::chrono::measurements::Filter::NO_OVERALL << std::chrono::measurements::Filter::NO_MAIN << std::chrono::measurements::results() << std::endl; + std::cout << "Tree print all - overall, main, finalize" << std::endl << std::chrono::measurements::Format::TREE << std::chrono::measurements::Filter::ALL << std::chrono::measurements::Filter::NO_OVERALL << std::chrono::measurements::Filter::NO_MAIN << std::chrono::measurements::Filter::NO_FINALIZE << std::chrono::measurements::results() << std::endl; + std::cout << "Tree print none + overall" << std::endl << std::chrono::measurements::Format::TREE << std::chrono::measurements::Filter::NONE << std::chrono::measurements::Filter::OVERALL << std::chrono::measurements::results() << std::endl; }