
" Performance Timer (From Smalltalk/V Course)
  By Tom Wrensch & Gene Korienek

  Here's a simple alternative to the millisecondsToRun:
  message in Time.  This timer works like a simple stop
  watch & can be used to time multiple events.  The
  only problem with it is the same as the problem with
  millisecondsToRun: - the time is only accurate to
  1/18th of a second on DOS machines and 1/60th of a
  second on Macs (I believe the number is 1/30th of a
  second for OS/2-PM).

  To time a piece of code just do this:

    | timer |
    timer := Timer new.
    timer start.
    1000 timesRepeat: [10 factorial].
    timer stop.
    timer totalTime

  The timer can also be used to time multiple events:

    | timer |
    timer :=  Timer new.
    timer start.
    1000 timesRepeat: [10 factorial].
    timer stop.
    timer time: [Smalltalk unusedMemory].
    timer totalTime.

  Remember the limitation on the timing resolution."!
    


Object subclass: #Timer
  instanceVariableNames: 
    'total events start '
  classVariableNames: ''
  poolDictionaries: '' !

!Timer class methods !

new
    "Answer an initialized instance"
^super new initialize! !


!Timer methods !

averageTime
    "Answer the average time for all events."
^total // events!

initialize
    "Private - Initialize the instance variables."
total := 0.
events := 0.
start := nil.!

start
    "Start timing an event."  
start := Time millisecondClockValue.!

stop
    "Stop timing an event."
| end |
end := Time millisecondClockValue.
end < start
    ifTrue: [end := end + (24 * 3600)].
total := total + (end - start).
events := events + 1.!

time: aBlock
    "Execute aBlock as a timed event."
self start.
aBlock value.
self stop.!

totalTime
    "Answer the total time for all events."
^total! !





