com.meliorbis.utils.Timer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Numerics Show documentation
Show all versions of Numerics Show documentation
A library for working with large multi-dimensional arrays and the functions they represent
package com.meliorbis.utils;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* A class that collects timings and can output the results. if an appropriate flag is
* set, the timer will do nothing
*
* @author Tobias Grasl
*
*/
public class Timer
{
public static final String DEFAULT = "Default";
public static final String TIMER_PROPERTY = "com.meliorbis.timer.off";
private static final boolean ON;
static
{
ON = !Boolean.getBoolean(TIMER_PROPERTY);
}
private final TimerInternal _internal;
public Timer()
{
this(ON);
}
/**
* Clears the map of timers. ONLY FOR TESTING!
*/
static void clearMap()
{
OnTimer._timerMap.clear();
}
public Timer(boolean on_)
{
_internal = on_ ? OnTimer.getInstance() : OFF_TIMER;
}
public void start()
{
_internal.start();
}
public Stoppable start(String id_)
{
return _internal.start(id_);
}
static public Map getTimesMap()
{
return OnTimer.getInstance().getTimesMap();
}
public void displayTimes()
{
_internal.displayTimes();
}
public interface Stoppable {
public void stop();
}
private interface TimerInternal
{
public Stoppable start();
public Map getTimesMap();
public Stoppable start(String id_);
public void displayTimes();
}
// DOES NOTHING!
private static final TimerInternal OFF_TIMER = new TimerInternal()
{
private final Stoppable _ind = new Stoppable()
{
@Override
public void stop()
{
// do nothing
}
};
@Override
public Stoppable start(String id_){return _ind;}
@Override
public Stoppable start(){return _ind;}
@Override
public void displayTimes(){}
@Override
public Map getTimesMap()
{
return Collections.emptyMap();
}
};
private static class OnTimer implements TimerInternal
{
private static HashMap _timerMap
= new HashMap();
private static final OnTimer _instance = new OnTimer();
static {
Runtime.getRuntime().addShutdownHook(new Thread()
{ @Override
public void run() {
_instance.displayTimes();
}
});
}
static OnTimer getInstance() {
return _instance;
}
private OnTimer(){}
@Override
public Stoppable start()
{
return start(DEFAULT);
}
@Override
public Stoppable start(String id_)
{
IndividualTimer timerForId = new IndividualTimer(id_);
timerForId.start();
return timerForId;
}
@Override
public void displayTimes()
{
for (IndividualTimer timer : _timerMap.values())
{
System.out.println(timer.toString());
}
}
@Override
public Map getTimesMap()
{
HashMap times = new HashMap<>();
for (IndividualTimer timer: _timerMap.values())
{
times.put(timer._id, new long[] {timer._totalTime, timer._count});
}
return times;
}
public class IndividualTimer implements Stoppable
{
long _totalTime = 0;
long _lastStart = -1;
int _count = 0;
private final String _id;
public IndividualTimer(String id_)
{
_id = id_;
}
public void start()
{
_lastStart = System.nanoTime();
}
public void stop()
{
if(_lastStart > 0)
{
_totalTime += System.nanoTime() - _lastStart;
_count++;
_lastStart = -1;
}
synchronized(_timerMap) {
IndividualTimer timerInMap = _timerMap.get(_id);
if(timerInMap == null)
{
_timerMap.put(_id, this);
}
else
{
timerInMap.mergeResults(this);
}
}
}
public void mergeResults(IndividualTimer other_)
{
_totalTime += other_._totalTime;
_count += other_._count;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
return String.format("%s total Time: %f (%d calls, %f mean)",_id,_totalTime/1e6, _count,((double)_totalTime/1e6)/_count);
}
}
}
}