com.redhat.ceylon.model.loader.Timer Maven / Gradle / Ivy
package com.redhat.ceylon.model.loader;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
public class Timer {
private long programStart;
private String currentTask;
private long currentTaskStart;
protected boolean verbose;
private final Map ignoredCategories;
protected PrintWriter out;
protected Timer(){
ignoredCategories = new HashMap();
}
private Timer(PrintWriter out, long programStart, boolean verbose, Map ignoredCategories) {
this.programStart = programStart;
this.verbose = verbose;
this.ignoredCategories = ignoredCategories;
this.out = out;
}
public Timer(boolean verbose) {
ignoredCategories = new HashMap();
setup(verbose);
}
private void setup(boolean verbose) {
// we delay printing the program start because we don't know if the verbose option is set yet at
// that time, so we fake it later on with the correct time
}
/**
* Initializes this timer and {@linkplain #log(String) logs} a
* "program start" message.
*/
public void init(){
programStart = System.nanoTime();
if(verbose)
log("Program start", programStart);
}
public void end() {
if(!verbose)
return;
log("Program end");
}
/**
* {@linkplain #endTask() Ends} the current task (if any) and starts a
* timed task with the given name,
* {@linkplain #log(String) logging} the task name.
*
* @param name The name of the task to start.
*
* @see #nestedTimer()
*/
public void startTask(String name){
if(!verbose)
return;
if(currentTask != null)
endTask();
currentTask = name;
currentTaskStart = System.nanoTime();
log("Task "+currentTask+" start");
}
/**
* Logs a message, including the elapsed time since this Timer was
* {@linkplain #init() initialized}.
* @param string The message
*/
public void log(String string) {
if(!verbose)
return;
log(string, System.nanoTime());
}
private void log(String string, long now) {
long delta = (now - programStart)/1_000_000;
String msg = "["+delta+"ms] "+string;
if(out != null)
out.println(msg);
else
System.err.println(msg);
}
/**
* Prints a message
* @param string The message
*/
public void print(String string) {
if(!verbose)
return;
if(out != null)
out.println(string);
else
System.err.println(string);
}
/**
* Ends the current task, {@linkplain #log(String) logging} the name of
* the task and its elapsed time
* @see #startTask(String)
*/
public void endTask() {
if(!verbose)
return;
long time = System.nanoTime();
long delta = (time - currentTaskStart)/1_000_000L;
log("Task "+currentTask+" end: "+delta+"ms");
printIgnoredCategories();
currentTask = null;
}
public void startIgnore(String category) {
if(!verbose)
return;
IgnoredCategory ignoredCategory = ignoredCategories.get(category);
if(ignoredCategory == null){
ignoredCategory = new IgnoredCategory(category);
ignoredCategories.put(category, ignoredCategory);
}
ignoredCategory.start();
}
public void stopIgnore(String category) {
if(!verbose)
return;
IgnoredCategory ignoredCategory = ignoredCategories.get(category);
if (ignoredCategory != null) {
ignoredCategory.stop();
}
}
private void printIgnoredCategories(){
for(IgnoredCategory category : ignoredCategories.values()){
if(category.total != 0){
print(" Including "+category.name+" for "+category.total+"ms");
}
category.reset();
}
}
private final class IgnoredCategory {
String name;
long start;
long total;
int count;
public IgnoredCategory(String category) {
this.name = category;
}
public void start() {
if(count++ == 0){
start = System.nanoTime();
}
}
public void stop() {
if(--count == 0){
long end = System.nanoTime();
long delta = (end - start)/1_000_000;
total += delta;
}
}
public void reset() {
if(count != 0)
print("Ignored category "+name+" count is "+count+" during reset: timings will be wrong");
// try to fix it for next time?
count = 0;
total = 0;
}
}
/**
* Creates and returns a new timer suitable for timing sub-tasks
* without stopping the 'outer' timer. Necessary because
* {@link #startTask(String)} stops the current timer.
* @return The new timer
*/
public Timer nestedTimer() {
return new Timer(out, programStart, verbose, ignoredCategories);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy