[Lemon-commits] [lemon_svn] alpar: r2408 - in hugo/trunk: benchmark doc lemon test

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:52:25 CET 2006


Author: alpar
Date: Mon Dec  5 18:03:31 2005
New Revision: 2408

Added:
   hugo/trunk/lemon/counter.h
   hugo/trunk/test/counter_test.cc
Modified:
   hugo/trunk/benchmark/bfs-bench.cc
   hugo/trunk/benchmark/graph-bench.cc
   hugo/trunk/benchmark/hcube.cc
   hugo/trunk/doc/groups.dox
   hugo/trunk/lemon/Makefile.am
   hugo/trunk/lemon/simann.h
   hugo/trunk/lemon/time_measure.h
   hugo/trunk/test/Makefile.am
   hugo/trunk/test/time_measure_test.cc

Log:
- 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.



Modified: hugo/trunk/benchmark/bfs-bench.cc
==============================================================================
--- hugo/trunk/benchmark/bfs-bench.cc	(original)
+++ hugo/trunk/benchmark/bfs-bench.cc	Mon Dec  5 18:03:31 2005
@@ -114,25 +114,25 @@
 //   cout << "Creating Hipercube ("<< (1<<dim) << " nodes, "
 //        << dim*(1<<dim) << " edges):";
 
-  T.reset();
+  T.restart();
   vector<Node> nodes;
   addBiDirHyperCube(G,dim,nodes);
 
   PrintTime("GENGRAPH",T);
 
-  T.reset();
+  T.restart();
   {
     for(int i=0;i<mul;i++)
       bfsStlQueue(G,nodes[0]);
   }
   PrintTime("BFS-STL",T);
-  T.reset();
+  T.restart();
   {
     for(int i=0;i<mul;i++)
       bfsOwnQueue(G,nodes[0]);
   }
   PrintTime("BFS-OWN",T);
-  T.reset();
+  T.restart();
   {
     for(int i=0;i<mul;i++)
       iteratorBench(G);

Modified: hugo/trunk/benchmark/graph-bench.cc
==============================================================================
--- hugo/trunk/benchmark/graph-bench.cc	(original)
+++ hugo/trunk/benchmark/graph-bench.cc	Mon Dec  5 18:03:31 2005
@@ -48,7 +48,7 @@
   makeFullGraph<ListGraph>(nextPrim(1000),nextPrim(300),nextPrim(100));
   
   PrintTime("BIG",T);
-  T.reset();
+  T.restart();
   makeFullGraph<ListGraph>(nextPrim(100),nextPrim(30000),nextPrim(150));
 
   PrintTime("SMALL",T);

Modified: hugo/trunk/benchmark/hcube.cc
==============================================================================
--- hugo/trunk/benchmark/hcube.cc	(original)
+++ hugo/trunk/benchmark/hcube.cc	Mon Dec  5 18:03:31 2005
@@ -52,13 +52,13 @@
 //   cout << "Creating Hipercube ("<< (1<<dim) << " nodes, "
 //        << dim*(1<<dim) << " edges):";
 
-  T.reset();
+  T.restart();
   vector<Node> nodes;
   addBiDirHyperCube(G,dim,nodes);
 
   PrintTime("GENGRAPH",T);
 
-  T.reset();
+  T.restart();
   Graph::EdgeMap<int> map(G);
   for(int i=0;i<5;i++) {
     Primes P;
@@ -84,7 +84,7 @@
   
   PrintTime("GENLENGTHS",T);
 
-  T.reset();
+  T.restart();
   {
     Dijkstra<Graph> Dij(G,map);
     for(int i=0;i<10;i++)
@@ -92,7 +92,7 @@
   }
   PrintTime("DIJKSTRA",T);
 
-  T.reset();
+  T.restart();
   {
    Graph::EdgeMap<int> flow(G);
    

Modified: hugo/trunk/doc/groups.dox
==============================================================================
--- hugo/trunk/doc/groups.dox	(original)
+++ hugo/trunk/doc/groups.dox	Mon Dec  5 18:03:31 2005
@@ -143,6 +143,13 @@
 */
 
 /**
+ at defgroup timecount Time measuring and Counting
+ at 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

Modified: hugo/trunk/lemon/Makefile.am
==============================================================================
--- hugo/trunk/lemon/Makefile.am	(original)
+++ hugo/trunk/lemon/Makefile.am	Mon Dec  5 18:03:31 2005
@@ -27,6 +27,7 @@
 	dfs.h \
 	bin_heap.h \
 	config.h \
+	counter.h \
 	dijkstra.h \
 	dimacs.h \
 	edge_set.h \

Added: hugo/trunk/lemon/counter.h
==============================================================================
--- (empty file)
+++ hugo/trunk/lemon/counter.h	Mon Dec  5 18:03:31 2005
@@ -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 <string>
+#include <iostream>
+
+///\ingroup timecount
+///\file
+///\brief Tools for counting steps and events
+
+namespace lemon 
+{
+
+  template<class P> class _SubNoCounter;
+
+  template<class P>
+  class _SubCounter 
+  {
+    P &_parent;
+    std::string _title;
+    std::ostream &_os;
+    int count;
+  public:
+
+    typedef _SubCounter<_SubCounter<P> > SubCounter;
+    typedef _SubNoCounter<_SubCounter<P> > 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 <<std::endl;
+      _parent+=count;
+    }
+    _SubCounter &operator++() { count++; return *this;}
+    int operator++(int) { return count++; }
+    _SubCounter &operator--() { count--; return *this;}
+    int operator--(int) { return count--; }
+    _SubCounter &operator+=(int c) { count+=c; return *this;}
+    _SubCounter &operator-=(int c) { count-=c; return *this;}
+    void reset(int c=0) {count=c;}
+    operator int() {return count;}
+  };
+
+  template<class P>
+  class _SubNoCounter 
+  {
+    P &_parent;
+  public:
+    typedef _SubNoCounter<_SubNoCounter<P> > SubCounter;
+    typedef _SubNoCounter<_SubNoCounter<P> > 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<Counter> SubCounter;
+    ///\e
+
+    ///\todo document please.
+    ///
+    typedef _SubNoCounter<Counter> 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 <<std::endl;
+    }
+    ///\e
+    Counter &operator++() { count++; return *this;}
+    ///\e
+    int operator++(int) { return count++;}
+    ///\e
+    Counter &operator--() { count--; return *this;}
+    ///\e
+    int operator--(int) { return count--;}
+    ///\e
+    Counter &operator+=(int c) { count+=c; return *this;}
+    ///\e
+    Counter &operator-=(int c) { count-=c; return *this;}
+    ///\e
+    void reset(int c=0) {count=c;}
+    ///\e
+    operator int() {return count;}
+  };
+
+  ///'Do nothing' version of \ref Counter
+
+  ///'Do nothing' version of \ref Counter.
+  ///\sa Counter
+  class NoCounter
+  {
+  public:
+    typedef _SubNoCounter<NoCounter> SubCounter;
+    typedef _SubNoCounter<NoCounter> 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

Modified: hugo/trunk/lemon/simann.h
==============================================================================
--- hugo/trunk/lemon/simann.h	(original)
+++ hugo/trunk/lemon/simann.h	Mon Dec  5 18:03:31 2005
@@ -301,7 +301,7 @@
           start_threshold = 5.0 * fabs(simann->getBestCost() - avg_cost);
           temp = 10000.0;
           warmup = false;
-          timer.reset();
+          timer.restart();
         }
       }
     }

Modified: hugo/trunk/lemon/time_measure.h
==============================================================================
--- hugo/trunk/lemon/time_measure.h	(original)
+++ hugo/trunk/lemon/time_measure.h	Mon Dec  5 18:03:31 2005
@@ -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.
+    ///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) {
+	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()
-    void stop() 
+    ///\sa restart()
+    ///\sa reset()
+
+    void halt() 
     {
-      if(running && !--running) {
+      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:

Modified: hugo/trunk/test/Makefile.am
==============================================================================
--- hugo/trunk/test/Makefile.am	(original)
+++ hugo/trunk/test/Makefile.am	Mon Dec  5 18:03:31 2005
@@ -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

Added: hugo/trunk/test/counter_test.cc
==============================================================================
--- (empty file)
+++ hugo/trunk/test/counter_test.cc	Mon Dec  5 18:03:31 2005
@@ -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 <lemon/counter.h>
+
+///\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;
+}

Modified: hugo/trunk/test/time_measure_test.cc
==============================================================================
--- hugo/trunk/test/time_measure_test.cc	(original)
+++ hugo/trunk/test/time_measure_test.cc	Mon Dec  5 18:03:31 2005
@@ -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;



More information about the Lemon-commits mailing list