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

com.google.gwt.dev.util.PerfCounter Maven / Gradle / Ivy

There is a newer version: 2.10.0
Show newest version
/*
 * Copyright 2009 Google Inc.
 * 
 * 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 com.google.gwt.dev.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * A counter which records bunch of statistics for frequently occuring 
 * operations. Calculates: count, total time, average time, maximum time 
 * & slow operations. 
 */
public class PerfCounter {
  private static class OperationStats {
    private long count = 0;
    private boolean isCounter = false;
    private long maxTimeNanos = 0;
    private long slowCount = 0;
    private long totalSlowTimeNanos = 0;
    private long totalTimeNanos = 0;
    
    @Override
    public String toString() {
      StringBuilder result = new StringBuilder();
      
      if (!isCounter) {
        result.append(count);
        result.append("/");
        result.append(totalTimeNanos / 1000000000.0);
        result.append("/");
        result.append(totalTimeNanos / 1000000000.0 / count);
        result.append("/");
        result.append(maxTimeNanos / 1000000000.0);
        result.append("/");
        result.append(slowCount);
        result.append("/");
        result.append(totalSlowTimeNanos * 1.0 / totalTimeNanos);
        result.append(" ");
        result.append(
            "(count/total_time/avg_time/max_time/slow_count/slow_ratio)");
      } else {
        result.append(count);
        result.append(" (count)");
      }
      
      return result.toString();
    }
  }

  /**
   * Flag for enabling performance logging.
   */
  private static boolean enabled = 
    Boolean.parseBoolean(System.getProperty("gwt.perfcounters"));
  
  private static final ThreadLocal> operationsStartTime = 
    new ThreadLocal>() {
    @Override
    protected Map initialValue() {
      return new HashMap();
    }
  };
  
  private static final Map operationStats = 
    new HashMap();
  
  /**
   * Record the end of the operation. 
   */
  public static void end(String operation) {
    if (!enabled) {
      return;
    }
    end(operation, 1 * 1000000000 /* 1 sec */);
  }
  
  /**
   * Record the end of the operation. 
   */
  public static void end(String operation, long slowThresholdNano) {
    if (!enabled) {
      return;
    }
    long finishTime = System.nanoTime();
    
    Map startTimes = operationsStartTime.get();
    
    Long startTime;
    
    synchronized (startTimes) {
      startTime = startTimes.remove(operation);
    }
    
    Preconditions.checkNotNull(startTime);
    
    synchronized (operationStats) {
      OperationStats stats = getStats(operation);
      
      stats.count++;
      long elapsedTime = finishTime - startTime.longValue();
      stats.totalTimeNanos += elapsedTime;
      stats.maxTimeNanos = Math.max(stats.maxTimeNanos, elapsedTime);
      if (elapsedTime > slowThresholdNano) {
        stats.slowCount++;
        stats.totalSlowTimeNanos += elapsedTime;
      }
    }
  }

  /**
   * Increment counter. 
   */
  public static void inc(String operation) {
    synchronized (operationStats) {
      OperationStats stats = getStats(operation);
      stats.count++;
      stats.isCounter = true;
    }
  }

  public static void print() {
    if (!enabled) {
      return;
    }
    System.out.println("------------- Perf Counters -------------");
    synchronized (operationStats) {
      List keys = new ArrayList(operationStats.keySet());
      Collections.sort(keys);
      for (String operation : keys) {
        System.out.println(operation + ": " + operationStats.get(operation));
      }
    }
    System.out.println("-----------------------------------------");
  }
  
  /**
   * Start operation.
   */
  public static void start(String operation) {
    if (!enabled) {
      return;
    }
    Map startTimes = operationsStartTime.get();
    
    synchronized (startTimes) {
      Preconditions.checkState(!startTimes.containsKey(operation));
      long startTime = System.nanoTime();
      startTimes.put(operation, new Long(startTime));
    }
  }

  private static OperationStats getStats(String operation) {
    OperationStats stats = operationStats.get(operation);
    if (stats == null) {
      stats = new OperationStats();
      operationStats.put(operation, stats);
    }
    return stats;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy