# HG changeset patch # User alpar # Date 1133802211 0 # Node ID 7cbc12e4248291457e314ec4806a1f2f2529ca37 # Parent 6b4e38acef1c9c7dc07a84215214ed12d5d6b44d - Changed and improved Timer interface - several new member functions - reset() -> restart() renaming - TimeReport: a Timer that prints a report on destruction. - counter.h: a tool to measure the number of streps of algorithms. - New documentation module for time measuring and counting. diff -r 6b4e38acef1c -r 7cbc12e42482 benchmark/bfs-bench.cc --- a/benchmark/bfs-bench.cc Sat Dec 03 18:30:31 2005 +0000 +++ b/benchmark/bfs-bench.cc Mon Dec 05 17:03:31 2005 +0000 @@ -114,25 +114,25 @@ // cout << "Creating Hipercube ("<< (1< nodes; addBiDirHyperCube(G,dim,nodes); PrintTime("GENGRAPH",T); - T.reset(); + T.restart(); { for(int i=0;i(nextPrim(1000),nextPrim(300),nextPrim(100)); PrintTime("BIG",T); - T.reset(); + T.restart(); makeFullGraph(nextPrim(100),nextPrim(30000),nextPrim(150)); PrintTime("SMALL",T); diff -r 6b4e38acef1c -r 7cbc12e42482 benchmark/hcube.cc --- a/benchmark/hcube.cc Sat Dec 03 18:30:31 2005 +0000 +++ b/benchmark/hcube.cc Mon Dec 05 17:03:31 2005 +0000 @@ -52,13 +52,13 @@ // cout << "Creating Hipercube ("<< (1< nodes; addBiDirHyperCube(G,dim,nodes); PrintTime("GENGRAPH",T); - T.reset(); + T.restart(); Graph::EdgeMap map(G); for(int i=0;i<5;i++) { Primes P; @@ -84,7 +84,7 @@ PrintTime("GENLENGTHS",T); - T.reset(); + T.restart(); { Dijkstra Dij(G,map); for(int i=0;i<10;i++) @@ -92,7 +92,7 @@ } PrintTime("DIJKSTRA",T); - T.reset(); + T.restart(); { Graph::EdgeMap flow(G); diff -r 6b4e38acef1c -r 7cbc12e42482 doc/groups.dox --- a/doc/groups.dox Sat Dec 03 18:30:31 2005 +0000 +++ b/doc/groups.dox Mon Dec 05 17:03:31 2005 +0000 @@ -143,6 +143,13 @@ */ /** +@defgroup timecount Time measuring and Counting +@ingroup misc +Here you can find simple tools for measuring the performance +of algorithms. +*/ + +/** @defgroup io_group Input Output Here you can find tools for imporing and exporting graphs and graph related data diff -r 6b4e38acef1c -r 7cbc12e42482 lemon/Makefile.am --- a/lemon/Makefile.am Sat Dec 03 18:30:31 2005 +0000 +++ b/lemon/Makefile.am Mon Dec 05 17:03:31 2005 +0000 @@ -27,6 +27,7 @@ dfs.h \ bin_heap.h \ config.h \ + counter.h \ dijkstra.h \ dimacs.h \ edge_set.h \ diff -r 6b4e38acef1c -r 7cbc12e42482 lemon/counter.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lemon/counter.h Mon Dec 05 17:03:31 2005 +0000 @@ -0,0 +1,171 @@ +/* -*- C++ -*- + * lemon/counter.h - + * Part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_COUNTER_H +#define LEMON_COUNTER_H + +#include +#include + +///\ingroup timecount +///\file +///\brief Tools for counting steps and events + +namespace lemon +{ + + template class _SubNoCounter; + + template + class _SubCounter + { + P &_parent; + std::string _title; + std::ostream &_os; + int count; + public: + + typedef _SubCounter<_SubCounter

> SubCounter; + typedef _SubNoCounter<_SubCounter

> SubNoCounter; + + _SubCounter(P &parent) + : _parent(parent), _title(), _os(std::cerr), count(0) {} + _SubCounter(P &parent,std::string title,std::ostream &os=std::cerr) + : _parent(parent), _title(title), _os(os), count(0) {} + _SubCounter(P &parent,const char *title,std::ostream &os=std::cerr) + : _parent(parent), _title(title), _os(os), count(0) {} + ~_SubCounter() { + _os << _title << count < + class _SubNoCounter + { + P &_parent; + public: + typedef _SubNoCounter<_SubNoCounter

> SubCounter; + typedef _SubNoCounter<_SubNoCounter

> SubNoCounter; + + _SubNoCounter(P &parent) :_parent(parent) {} + _SubNoCounter(P &parent,std::string title,std::ostream &os=std::cerr) + :_parent(parent) {} + _SubNoCounter(P &parent,const char *title,std::ostream &os=std::cerr) + :_parent(parent) {} + ~_SubNoCounter() {} + _SubNoCounter &operator++() { ++_parent; return *this;} + int operator++(int) { _parent++; return 0;} + _SubNoCounter &operator--() { --_parent; return *this;} + int operator--(int) { _parent--; return 0;} + _SubNoCounter &operator+=(int c) { _parent+=c; return *this;} + _SubNoCounter &operator-=(int c) { _parent-=c; return *this;} + void reset(int c=0) {} + operator int() {return 0;} + }; + + + /// \addtogroup timecount + /// @{ + + ///A counter class + + ///This class makes it easier to count certain events. You can increment + ///or decrement the counter using operator++ and operator--. + ///A report is automatically printed on destruction. + class Counter + { + std::string _title; + std::ostream &_os; + int count; + public: + ///\e + + ///\todo document please. + /// + typedef _SubCounter SubCounter; + ///\e + + ///\todo document please. + /// + typedef _SubNoCounter SubNoCounter; + + ///\e + Counter() : _title(), _os(std::cerr), count(0) {} + ///\e + Counter(std::string title,std::ostream &os=std::cerr) + : _title(title), _os(os), count(0) {} + ///\e + Counter(const char *title,std::ostream &os=std::cerr) + : _title(title), _os(os), count(0) {} + ///Destructor. Prints the given title and the value of the counter. + ~Counter() { + _os << _title << count < SubCounter; + typedef _SubNoCounter SubNoCounter; + + NoCounter() {} + NoCounter(std::string title,std::ostream &os=std::cerr) {} + NoCounter(const char *title,std::ostream &os=std::cerr) {} + NoCounter &operator++() { return *this; } + int operator++(int) { return 0; } + NoCounter &operator--() { return *this; } + int operator--(int) { return 0; } + NoCounter &operator+=(int c) { return *this;} + NoCounter &operator-=(int c) { return *this;} + void reset(int c=0) {} + operator int() {return 0;} + }; + + ///@} +} + +#endif diff -r 6b4e38acef1c -r 7cbc12e42482 lemon/simann.h --- a/lemon/simann.h Sat Dec 03 18:30:31 2005 +0000 +++ b/lemon/simann.h Mon Dec 05 17:03:31 2005 +0000 @@ -4,6 +4,9 @@ /// \ingroup experimental /// \file /// \brief Simulated annealing framework. +/// +/// \todo A test and some demo should be added +/// \todo Doc should be improved /// \author Akos Ladanyi #include @@ -298,7 +301,7 @@ start_threshold = 5.0 * fabs(simann->getBestCost() - avg_cost); temp = 10000.0; warmup = false; - timer.reset(); + timer.restart(); } } } diff -r 6b4e38acef1c -r 7cbc12e42482 lemon/time_measure.h --- a/lemon/time_measure.h Sat Dec 03 18:30:31 2005 +0000 +++ b/lemon/time_measure.h Mon Dec 05 17:03:31 2005 +0000 @@ -17,7 +17,7 @@ #ifndef LEMON_TIME_MEASURE_H #define LEMON_TIME_MEASURE_H -///\ingroup misc +///\ingroup timecount ///\file ///\brief Tools for measuring cpu usage @@ -29,7 +29,7 @@ namespace lemon { - /// \addtogroup misc + /// \addtogroup timecount /// @{ /// A class to store (cpu)time instances. @@ -209,7 +209,7 @@ /// Timer T; /// doSomething(); /// std::cout << T << '\n'; - /// T.reset(); + /// T.restart(); /// doSomethingElse(); /// std::cout << T << '\n'; /// @@ -223,7 +223,8 @@ ///running times. /// ///\warning Depending on the operation system and its actual configuration - ///the time counters have a certain (relatively big) granularity. + ///the time counters have a certain (10ms on a typical Linux system) + ///granularity. ///Therefore this tool is not appropriate to measure very short times. ///Also, if you start and stop the timer very frequently, it could lead ///distorted results. @@ -238,18 +239,18 @@ ///\author Alpar Juttner class Timer { - int running; //Timer is running iff running>0; (running>=0 always holds) + int _running; //Timer is running iff _running>0; (_running>=0 always holds) TimeStamp start_time; //This is the relativ start-time if the timer - //is running, the collected running time otherwise. + //is _running, the collected _running time otherwise. - void _reset() {if(running) start_time.stamp(); else start_time.reset();} + void _reset() {if(_running) start_time.stamp(); else start_time.reset();} public: ///Constructor. ///\param _running indicates whether or not the timer starts immediately. /// - Timer(bool _running=true) :running(_running) {_reset();} + Timer(bool run=true) :_running(run) {_reset();} ///Computes the ellapsed time @@ -259,15 +260,16 @@ { TimeStamp t; t.stamp(); - return running?t-start_time:start_time; + return _running?t-start_time:start_time; } - ///Resets the time counters + ///Reset and stop the time counters - ///Resets the time counters - /// + ///This function resets and stops the time counters + ///\sa restart() void reset() { + _running=0; _reset(); } @@ -280,27 +282,74 @@ ///\sa stop() void start() { - if(running) running++; + if(_running) _running++; else { TimeStamp t; t.stamp(); start_time=t-start_time; } } + ///Stop the time counters - ///This function stops the time counters. - /// - ///\sa stop() + ///This function stops the time counters. If start() was executed more than + ///once, then the same number of stop() execution is necessary the really + ///stop the timer. + /// + ///\sa halt() + ///\sa start() + ///\sa restart() + ///\sa reset() + void stop() { - if(running && !--running) { + if(_running && !--_running) { TimeStamp t; t.stamp(); start_time=t-start_time; } } + + ///Halt (i.e stop immediately) the time counters + + ///This function stops immediately the time counters. + /// + ///\sa stop() + ///\sa restart() + ///\sa reset() + + void halt() + { + if(_running) { + _running=0; + TimeStamp t; + t.stamp(); + start_time=t-start_time; + } + } + + ///Returns the running state of the timer + + ///This function returns the number of stop() exections that is + ///necessary to really stop the timer. + ///For example the timer + ///is running if and only if the return value is \c true + ///(i.e. greater than + ///zero). + int running() { return _running; } + + + ///Restart the time counters + + ///This function is a shorthand for + ///a reset() and a start() calls. + /// + void restart() + { + reset(); + start(); + } ///Gives back the ellapsed user time of the process double userTime() const @@ -330,6 +379,25 @@ }; + ///Same as \ref Timer but prints a report on destruction. + + ///Same as \ref Timer but prints a report on destruction. + ///\todo Untested + class TimeReport : public Timer + { + std::string _title; + std::ostream &_os; + public: + ///\e + + TimeReport(std::string title,std::ostream &os,bool run) + : Timer(run), _title(title), _os(os){} + ~TimeReport() + { + _os << _title << this << std::endl; + } + }; + ///Prints the time counters ///Prints the time counters in the following form: diff -r 6b4e38acef1c -r 7cbc12e42482 test/Makefile.am --- a/test/Makefile.am Sat Dec 03 18:30:31 2005 +0000 +++ b/test/Makefile.am Mon Dec 05 17:03:31 2005 +0000 @@ -13,6 +13,7 @@ check_PROGRAMS = \ all_pairs_shortest_path_test \ bfs_test \ + counter_test \ dfs_test \ dijkstra_test \ graph_test \ @@ -48,6 +49,7 @@ all_pairs_shortest_path_test_SOURCES = all_pairs_shortest_path_test.cc bfs_test_SOURCES = bfs_test.cc +counter_test_SOURCES = counter_test.cc dfs_test_SOURCES = dfs_test.cc dijkstra_test_SOURCES = dijkstra_test.cc graph_test_SOURCES = graph_test.cc diff -r 6b4e38acef1c -r 7cbc12e42482 test/counter_test.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/counter_test.cc Mon Dec 05 17:03:31 2005 +0000 @@ -0,0 +1,64 @@ +/* -*- C++ -*- + * test/counter_test.cc - Part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +///\file \brief Test cases for time_measure.h +/// +///\todo To be extended + + +int fibonacci(int f) +{ + static lemon::Counter count("Fibonacci steps: "); + count++; + if(f<1) return 0; + else if(f==1) return 1; + else return fibonacci(f-1)+fibonacci(f-2); +} + +int main() +{ + fibonacci(10); + + { + typedef lemon::Counter MyCounter; + MyCounter c("Main counter: "); + c++; + c++; + MyCounter::SubCounter d(c,"Subcounter: "); + d++; + d++; + MyCounter::SubCounter::SubCounter e(d,"SubSubCounter: "); + e++; + e++; + } + + { + typedef lemon::NoCounter MyCounter; + MyCounter c("Main counter: "); + c++; + c++; + MyCounter::SubCounter d(c,"Subcounter: "); + d++; + d++; + MyCounter::SubCounter::SubCounter e(d,"SubSubCounter: "); + e++; + e++; + } + + return 0; +} diff -r 6b4e38acef1c -r 7cbc12e42482 test/time_measure_test.cc --- a/test/time_measure_test.cc Sat Dec 03 18:30:31 2005 +0000 +++ b/test/time_measure_test.cc Mon Dec 05 17:03:31 2005 +0000 @@ -36,7 +36,7 @@ int n; for(n=0;T.realTime()<1.0;n++) ; std::cout << T << " (" << n << " time queries)\n"; - T.reset(); + T.restart(); while(T.realTime()<2.0) ; std::cout << T << '\n'; TimeStamp full;