All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.meliorbis.utils.Timer Maven / Gradle / Ivy

Go to download

A library for working with large multi-dimensional arrays and the functions they represent

There is a newer version: 1.2
Show newest version
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);
			}
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy