Skip to content
Snippets Groups Projects
Commit eb2ef405 authored by Jan Trávníček's avatar Jan Trávníček
Browse files

continue on measurements implementation

parent 686fda12
No related branches found
No related tags found
No related merge requests found
......@@ -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;
......
......@@ -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) {
......
......@@ -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;
}
 
......
......@@ -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 */
......
......@@ -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 */
......@@ -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.
......
......@@ -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_ */
/*
* 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 */
......@@ -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 */
......
......@@ -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;
}
 
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment