package edu.brown.profilers; import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; import edu.brown.logging.LoggerUtil; import edu.brown.logging.LoggerUtil.LoggerBoolean; import edu.brown.utils.StringUtil; public abstract class ProfileMeasurementUtil { private static final Logger LOG = Logger.getLogger(ProfileMeasurementUtil.class); private static final LoggerBoolean debug = new LoggerBoolean(); private static final LoggerBoolean trace = new LoggerBoolean(); static { LoggerUtil.attachObserver(LOG, debug, trace); } // -------------------------------------------------------------------------------------------- // SWAP METHODS // -------------------------------------------------------------------------------------------- /** * Stop one of the given ProfileMeasurement handles and start the other * * @param to_stop * the handle to stop * @param to_start * the handle to start */ public static void swap(ProfileMeasurement to_stop, ProfileMeasurement to_start) { ProfileMeasurementUtil.swap(ProfileMeasurement.getTime(), to_stop, to_start); } public static void swap(long timestamp, ProfileMeasurement to_stop, ProfileMeasurement to_start) { if (debug.val) LOG.debug(String.format("SWAP %s -> %s", to_stop, to_start)); to_stop.stopIfStarted(timestamp); to_start.start(timestamp); } // -------------------------------------------------------------------------------------------- // STOP METHODS // -------------------------------------------------------------------------------------------- /** * Stop the given ProfileMeasurements at the given timestamp if they * have been started. * @param timestamp * @param pms */ public static void stopIfStarted(long timestamp, ProfileMeasurement...pms) { for (ProfileMeasurement pm : pms) { if (pm.isStarted()) pm.stop(timestamp); } // FOR } /** * Stop multiple ProfileMeasurements with the same timestamp If * ignore_stopped is true, we won't stop ProfileMeasurements that already * stopped * * @param ignore_stopped * @param to_stop */ public static void stop(boolean ignore_stopped, ProfileMeasurement... to_stop) { long time = ProfileMeasurement.getTime(); for (ProfileMeasurement pm : to_stop) { synchronized (pm) { if (ignore_stopped == false || (ignore_stopped && pm.isStarted())) pm.stop(time); } // SYNCH } // FOR } /** * Stop multiple ProfileMeasurements with the same timestamp * * @param to_stop */ public static void stop(ProfileMeasurement... to_stop) { stop(false, to_stop); } // -------------------------------------------------------------------------------------------- // START METHODS // -------------------------------------------------------------------------------------------- public static void start(boolean ignore_started, ProfileMeasurement... to_start) { long time = ProfileMeasurement.getTime(); for (ProfileMeasurement pm : to_start) { synchronized (pm) { if (ignore_started == false || (ignore_started && pm.isStarted() == false)) pm.start(time); } // SYNCH } // FOR } /** * Start multiple ProfileMeasurements with the same timestamp * * @param to_start */ public static void start(ProfileMeasurement... to_start) { start(false, to_start); } // -------------------------------------------------------------------------------------------- // PRETTY PRINTING // -------------------------------------------------------------------------------------------- public static String debug(ProfileMeasurement pm) { return String.format("%.2fms total / %s avg", pm.getTotalThinkTimeMS(), StringUtil.formatTime("%.2f", pm.getAverageThinkTime())); } /** * Create a single-line that shows the delta for a given ProfileMeasurement * from a previous one. * @param pm * @param last * @param showInvocations * @return */ public static String formatComparison(ProfileMeasurement pm, ProfileMeasurement last, boolean showInvocations) { final String separator = "/"; StringBuilder value = new StringBuilder(); if (showInvocations) { value.append(String.format("%d invocations %s ", pm.getInvocations(), separator)); } value.append(ProfileMeasurementUtil.debug(pm)); if (last != null) { value.append(" ["); for (int i = 0; i < 2; i++) { if (i > 0) value.append(" ").append(separator).append(" "); String deltaPrefix = ""; double delta; // TOTAL if (i == 0) { delta = pm.getTotalThinkTime() - last.getTotalThinkTime(); deltaPrefix = "TOTAL: "; } // AVERAGE else { delta = pm.getAverageThinkTime() - last.getAverageThinkTime(); deltaPrefix = "AVG: "; } String deltaTime = StringUtil.formatTime("%.2f", delta, TimeUnit.NANOSECONDS); String deltaArrow = ""; if (delta > 0) { deltaArrow = StringUtil.UNICODE_UP_ARROW; } else if (delta < 0) { deltaArrow = StringUtil.UNICODE_DOWN_ARROW; } value.append(deltaPrefix + deltaArrow + deltaTime); } // FOR value.append("]"); } return (value.toString()); } }