/* * #! * Ontopia Vizigator * #- * Copyright (C) 2001 - 2013 The Ontopia Project * #- * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * !# */ package net.ontopia.topicmaps.viz; public class PerformanceStat { protected long sum; protected long sumOfSquares; protected long count; protected long min; protected long max; protected long initTime; protected long startTime; protected String id; protected boolean showIndividuals; public PerformanceStat(String id) { // NB! Put this test at the top of all dynamic methods in this class. if (!VizDebugUtils.isDebugEnabled()) return; this.id = id; } public void init() { // NB! Put this test at the top of all dynamic methods in this class. if (!VizDebugUtils.isDebugEnabled()) return; sum = 0; sumOfSquares = 0; count = 0; showIndividuals = false; initTime = System.currentTimeMillis(); } public void setShowIndividuals(boolean showIndividuals) { // NB! Put this test at the top of all dynamic methods in this class. if (!VizDebugUtils.isDebugEnabled()) return; this.showIndividuals = showIndividuals; } public void startOp() { // NB! Put this test at the top of all dynamic methods in this class. if (!VizDebugUtils.isDebugEnabled()) return; startTime = System.currentTimeMillis(); } public void stopOp() { // NB! Put this test at the top of all dynamic methods in this class. if (!VizDebugUtils.isDebugEnabled()) return; long currentTime = System.currentTimeMillis() - startTime; count++; sum += currentTime; sumOfSquares += currentTime * currentTime; if (count == 1 || currentTime < min) min = currentTime; if (count == 1 || currentTime > max) max = currentTime; if (showIndividuals) VizDebugUtils.debug("Value(" + id + "): " + String.valueOf(currentTime)); } public void report() { // NB! Put this test at the top of all dynamic methods in this class. if (!VizDebugUtils.isDebugEnabled()) return; long reportMakingStartTime = System.currentTimeMillis(); VizDebugUtils.debug("--------------------------------------------------" + "--------------------------------------------------"); VizDebugUtils.debug("PerformanceStat - Report (" + id + ")"); VizDebugUtils.debug("--------------------------------------------------" + "--------------------------------------------------"); if (count == 0) { VizDebugUtils.debug(" No iterations executed."); return; } long overallTime = System.currentTimeMillis() - initTime; long average = sum / count; double standardDeviation = standardDev(sum, sumOfSquares, count); int sdPercentageAvg = (int)(standardDeviation * 100 / average); int percentage = (int)(((double)sum) * 100 / overallTime); long reportMakingTime = System.currentTimeMillis() - reportMakingStartTime; int reportMakingPercentage = (int)(((double)reportMakingTime) * 100 / overallTime); VizDebugUtils.debug(" Overall time: " + VizDebugUtils.formatTimeDeltaValue(overallTime)); VizDebugUtils.debug(" Report time: " + VizDebugUtils.formatTimeDeltaValue(reportMakingTime) + "(" + reportMakingPercentage + "%)"); VizDebugUtils.debug(" Sum times: " + VizDebugUtils.formatTimeDeltaValue(sum) + "(" + percentage + "%)"); VizDebugUtils.debug(" Count times: " + count); VizDebugUtils.debug(" Average time: " + VizDebugUtils.formatTimeDeltaValue(average)); VizDebugUtils.debug(" Minimum time: " + VizDebugUtils.formatTimeDeltaValue(min)); VizDebugUtils.debug(" Maximum time: " + VizDebugUtils.formatTimeDeltaValue(max)); VizDebugUtils.debug(" Standard deviation: " + VizDebugUtils.formatTimeDeltaValue((long)standardDeviation) + "(" + sdPercentageAvg + "% of average)"); } /** * Given the sum of the values, the sum of the squares of the values and the * number of values in a collection numbers, calculates the standard deviation * @param sum The sum of the values. * @param sumOfSquares The sum of the squares of the values. * @param count The number of values. * @return The standard deviation of the values. */ public static double standardDev(long sum, long sumOfSquares, long count) { /* * The variance is equal to the sum of the squares of each data item minus the * mean value. All of this is devided by the number of data items. I.e.: * variance = sum[i in 1 to n](sq(xi - mean)) / n * = sum[i in 1 to n](sq(xi) - 2 * xi * mean + square(mean)) / n * = (sum[i in 1 to n](sq(xi)) * - 2 * mean * sum[i in 1 to n](xi) * + n * square(mean)) / n * = (sum[i in 1 to n](sq(xi)) * + mean * (n * mean - 2 * sum[i in 1 to n](xi))) / n * = (sum[i in 1 to n](sq(xi)) * + mean * (sum[i in 1 to n](xi) - 2 * sum[i in 1 to n](xi)) * ) / n * = (sum[i in 1 to n](sq(xi)) - mean * sum[i in 1 to n](xi)) / n * = sumOfSquares / count - square(mean) * Having preprocessed all the sums of the data, the variance, and thus the * standard deviation can be calculated without traversing the raw data, * and hence without building up a collection. * This can save a lot of memory when monitoring large topic maps. */ double mean = ((double)sum) / count; double variance = sumOfSquares / count - mean * mean; double sd = Math.sqrt(variance); return sd; } }