[comp.lang.c++] Timer

keffer@blake.acs.washington.edu (Thomas Keffer) (06/17/89)

Here's a handy timer for profiling a program on the cheap.  It's so
small, I include it here.  It was written by Bruce Eckel while he was
working here on the DAIMS project.  It works under Sun OS and probably
other BSD systems.  Not sure about other systems.

To use:

#include <Timer.h>
main()
{
	Timer t;

	/*... some stuff ...*/
	t.mark("I am here");
	/*... more stuff ...*/
	t.mark("Now here");
	
	cout << t;
}
---
 Dr. Thomas Keffer          | Internet: keffer@sperm.ocean.washington.edu
 School of Oceanography     | BITNET:   keffer%sperm.ocean.washington.edu@UWAVM
 Univ. of Washington, WB-10 | uucp:     uw-beaver!sperm.ocean.washington.edu!keffer
 Seattle, WA 98195          | Telemail: T.KEFFER/OMNET
    (206) 543-6455

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	Timer.h
#	timer.cc
# This archive created: Fri Jun 16 14:18:27 1989
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'Timer.h'
then
	echo shar: "will not over-write existing file 'Timer.h'"
else
cat << \SHAR_EOF > 'Timer.h'
#ifndef TIMER_H
#define TIMER_H
#pragma once

/*
 *	
 *	Written by
 *
 *	Bruce Eckel
 *	School of Oceanography; WB-10
 *	University of Washington
 *	Seattle, WA 98195
 *
 *	As part of the DAIMS project.  For more information, contact:
 *
 *	Tom Keffer
 *	keffer@ocean.washington.edu
 */

#include <sys/time.h>
#include <sys/resource.h>
#include <stream.h>

/* 
-*++ class timer: measures use of system resources
** 
** (*++ history: 
** 	27 Apr 88	Bruce Eckel	Creation date
** ++*)
** 
** (*++ detailed: Whenever you want to measure a point, use the "mark"
** function.  Everything will be dumped out at the end when you're done. 
** ++*)
*/

struct MarkPoint {
    float seconds;
    char * msg;
    MarkPoint * next;
};

class Timer {
    MarkPoint * head;
    MarkPoint * current;
    void timer_(float * secs);
  public: 
    Timer();
    ~Timer();
    void mark();
    void mark(char * msg);
    friend ostream& operator<<(ostream &, Timer & );  /* send to stream */
};

#endif TIMER_H
SHAR_EOF
fi
if test -f 'timer.cc'
then
	echo shar: "will not over-write existing file 'timer.cc'"
else
cat << \SHAR_EOF > 'timer.cc'
/*
 *	
 *	Written by
 *
 *	Bruce Eckel
 *	School of Oceanography; WB-10
 *	University of Washington
 *	Seattle, WA 98195
 *
 *	%W%	%G%
 */

#include "Timer.h"

extern int getrusage(int, struct rusage*);

void
Timer::timer_(float *seconds)
{
  struct rusage use;
  double usertime, systime;

  getrusage(RUSAGE_SELF, &use);

  usertime = (double)use.ru_utime.tv_sec +
    ((double)use.ru_utime.tv_usec)/1.0e6;

  systime = (double)use.ru_stime.tv_sec +
    ((double)use.ru_stime.tv_usec)/1.0e6;

  *seconds = (float)(usertime + systime);

  return;
}


 Timer::Timer()
{
    current = head = new MarkPoint;
    head->next = 0;
}


/* 
-*++ Timer::~Timer(): 
** 
** (*++ history: 
** 	27 Apr 88	Bruce Eckel	Creation date
** ++*)
** 
** (*++ detailed: 
** ++*)
*/

void Timer::~Timer()
{
    MarkPoint * ptr = head;
    MarkPoint * killptr;
    while (ptr) {
	killptr = ptr;
	if (ptr->next) 
	    ptr = ptr->next;
	else ptr = 0;
	delete killptr->msg;
	delete killptr;
    }
}
    

/* 
-*++ Timer::mark(): mark timing information at this point in the program
** 
** (*++ history: 
** 	27 Apr 88	Bruce Eckel	Creation date
** ++*)
** 
** (*++ detailed: 
** ++*)
*/

void Timer::mark()
{
    timer_(&(current->seconds));
    current->msg = new char[ strlen("Marker ") + 1 ];
    strcpy(current->msg,"Marker ");
    current->next = new MarkPoint;
    current = current->next;
    current->next = (MarkPoint *)0; /* denote end of list */
    current->seconds = 0;
}


/* 
-*++ Timer::mark(): place a marker with a message
** 
** (*++ history: 
** 	27 Apr 88	Bruce Eckel	Creation date
** ++*)
** 
** (*++ detailed: 
** ++*)
*/

void Timer::mark(char * message)
{
    timer_(&(current->seconds));
    current->msg = new char[ strlen(message) + 1 ];
    strcpy(current->msg,message);
    current->next = new MarkPoint;
    current = current->next;
    current->next = (MarkPoint *)0; /* denote end of list */
    current->seconds = 0;
}

/* 
-*++ operator<<(): how to output timing information via streams
** 
** (*++ history: 
** 	27 Apr 88	Bruce Eckel	Creation date
** ++*)
** 
** (*++ detailed: 
** ++*)
*/

ostream& operator<<(ostream & s, Timer & t)
{
    int i = 1;
    MarkPoint * ptr = t.head;
    while (ptr->next) {
	s << "Marker " << i << ": " << ptr->msg << ": time = ";
	s << ptr-> seconds << "\n";
	if (ptr->next) ptr = ptr->next;
	else break;
	i++;
    } 
    return s;
}

SHAR_EOF
fi
exit 0
#	End of shell archive