/*
* WPCleaner: A tool to help on Wikipedia maintenance tasks.
* Copyright (C) 2013 Nicolas Vervelle
*
* See README.txt file for licensing information.
*/
package org.wikipediacleaner.utils;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
/**
* Utility class to measure performance.
*/
public class Performance {
/** Stream to write performance information to */
private final static PrintStream output = System.err;
/** Global flag for printing */
private static boolean print = true;
/** Global flag for using high precision */
private static boolean highPrecision = false;
/** Method name */
private final String method;
/** Unit of time */
private final String unit;
/** Initial time */
private long initialTime;
/** Last time */
private long lastTime;
/** Threshold for printing duration */
private long threshold;
/** Map to measure parts of the execution */
private Map<String, Long> parts;
/** Initial time for a part of the execution */
private long partInitialTime;
/**
* @param method Method name.
*/
public Performance(String method) {
this(method, 0);
}
/**
* @param method Method name.
* @param threshold Threshold for printing results.
*/
public Performance(String method, long threshold) {
this.method = method;
this.unit = highPrecision ? "ns" : "ms";
this.threshold = threshold;
initialTime = currentTime();
partInitialTime = initialTime;
lastTime = initialTime;
}
/**
* @param threshold Threshold for printing duration.
*/
public void setThreshold(long threshold) {
this.threshold = threshold;
}
/**
* Print a message.
*
* @param message Message to be printed.
*/
private void printMessage(String message) {
if (print) {
output.print(method);
if (message != null) {
output.print(": ");
output.print(message);
}
output.println();
output.flush();
}
}
/**
* Print a message.
*
* @param time Current time.
* @param message Message to be printed.
*/
@SuppressWarnings("unused")
private void printTimedMessage(long time, String message) {
if (print) {
output.print(time);
output.print(" - ");
output.print(method);
if (message != null) {
output.print(": ");
output.print(message);
}
output.println();
output.flush();
}
}
/**
* Print a start message.
*/
public void printStart() {
initialTime = currentTime();
lastTime = initialTime;
printMessage(null);
}
/**
* Print a step message.
*
* @param message Message to be printed.
*/
public void printStep(String message) {
long time = currentTime();
printMessage("(" + (time - lastTime) + unit + ") " + message);
lastTime = time;
}
/**
* Start measuring time for a part of the execution.
*/
public void startPart() {
partInitialTime = currentTime();
}
/**
* Stop measuring time for a part of the execution.
*
* @param part Part name.
*/
public void stopPart(String part) {
long time = currentTime();
if (time <= partInitialTime) {
return;
}
if (parts == null) {
parts = new HashMap<String, Long>();
}
Long previousTime = parts.get(part);
if (previousTime != null) {
parts.put(part, Long.valueOf(time - partInitialTime + previousTime.longValue()));
} else {
parts.put(part, Long.valueOf(time - partInitialTime));
}
partInitialTime = time;
}
/**
* Print an end message.
*/
public void printEnd() {
long time = currentTime();
if (time > initialTime + threshold) {
printDetail("(" + (time - initialTime) + unit + ")");
}
}
/**
* Print an end message.
*/
public void printEnd(String message) {
long time = currentTime();
if (time > initialTime + threshold) {
printDetail(message + "(" + (time - initialTime) + unit + ")");
}
}
/**
* Print an end message.
*/
public void printEnd(String message, String message2) {
long time = currentTime();
if (time > initialTime + threshold) {
printDetail(message + ":" + message2 + "(" + (time - initialTime) + unit + ")");
}
}
private void printDetail(String message) {
printMessage(message);
if (parts != null) {
for (Entry<String, Long> entry : parts.entrySet()) {
printMessage(" " + entry.getKey() + "(" + entry.getValue() + unit + ")");
}
}
}
/**
* @return Current time.
*/
private static long currentTime() {
if (highPrecision) {
return System.nanoTime();
}
return System.currentTimeMillis();
}
}