Package org.apache.niolex.commons.test

Source Code of org.apache.niolex.commons.test.StopWatch$Stop

/**
* StopWatch.java
*
* Copyright 2012 Niolex, Inc.
*
* Niolex licenses this file to you 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 org.apache.niolex.commons.test;

import java.text.NumberFormat;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.niolex.commons.util.Runme;

/**
* This class is calculating average time, max time, min time, time distribution.
* Often needed for pressure test.
*
* @author <a href="mailto:xiejiyun@gmail.com">Xie, Jiyun</a>
* @version 1.0.0
* @since 2012-8-14
*/
public class StopWatch {

  private final int distributionInterval;
  private final ConcurrentLinkedQueue<Integer> linkList = new ConcurrentLinkedQueue<Integer>();

  // These three variables are for rps calculation.
  private final LinkedList<Long> rpsList = new LinkedList<Long>();
  private final AtomicLong counter = new AtomicLong(0);
  private Runme rumme;

  private long startTime;
  private int[] distributions;
  private int avg;
  private int max;
  private int min;
  private int rps;

  /**
   * Construct a new Stop Watch.
   *
   * @param distributionInterval The interval to calculate distribution.
   */
  public StopWatch(int distributionInterval) {
    super();
    this.distributionInterval = distributionInterval;
  }

  /**
   * Begin the time calculation.
   *
   * @param printDirectly Whether to print RPS directly into console.
   */
  public void begin(final boolean printDirectly) {
    startTime = System.currentTimeMillis();
    counter.getAndSet(0);

    rumme = new Runme() {

      @Override
      public void runMe() {
        Long l = counter.getAndSet(0);
        if (printDirectly) {
          System.out.println("rps -> " + l);
        } else {
          rpsList.add(l);
        }
      }

    };

    rumme.setInitialSleep(true);
    rumme.start();
  }

  /**
   * Start a new time counter to count the current unit running time.
   * This method can be called in parallel.
   *
   * @return a Stop object.
   */
  public Stop start() {
    return new Stop();
  }

  /**
   * Mark this Stop Watch as done and calculate all the statistics.
   */
  public void done() {
    if (rumme != null) {
      rumme.stopMe();
    }
    final int distNum = 1000 / distributionInterval + 1;
    final long wholeTime = System.currentTimeMillis() - startTime;
    long totalCnt = 0, totalTime = 0;
    distributions = new int[distNum];
    max = 0;
    min = Integer.MAX_VALUE;
    Integer c;
    while ((c = linkList.poll()) != null) {
      int i = c.intValue();
      ++totalCnt;
      totalTime += i;
      if (i > max) max = i;
      if (i < min) min = i;
      int k = i / distributionInterval;
      if (k >= distNum) k = distNum - 1;
      ++distributions[k];
    }
    avg = (int) (totalTime / totalCnt);
    rps = (int) (totalCnt * 1000 / wholeTime);
  }

  /**
   * Print all the statistics into console.
   */
  public void print() {
    StringBuilder sb = new StringBuilder();
    sb.append("\n\n---------------------------------------\n");
    sb.append("MAX\tMIN\tAVG\tRPS\n");
    sb.append(max).append('\t').append(min).append('\t').append(avg).append('\t');
    sb.append(rps).append('\n');
    sb.append("---------------------------------------\n");
    int l = 0, r = distributionInterval;
    NumberFormat nf = NumberFormat.getIntegerInstance();
    NumberFormat rf = NumberFormat.getIntegerInstance();
    nf.setMinimumIntegerDigits(3);
    rf.setGroupingUsed(true);
    rf.setMinimumIntegerDigits(6);
    for (int i = 0; i < distributions.length; ++i) {
      if (distributions[i] > 0) {
        sb.append(nf.format(l)).append(" to ");
        if (i == distributions.length - 1) {
          sb.append('~');
        } else {
          sb.append(nf.format(r));
        }
        sb.append("\t").append(rf.format(distributions[i])).append('\n');
      }
      l = r;
      r += distributionInterval;
    }
    sb.append("---------------------------------------\n");
    Iterator<Long> it = rpsList.iterator();
    while (it.hasNext()) {
      sb.append(rf.format(it.next())).append('\n');
    }
    sb.append("----------------END--------------------\n");
    System.out.print(sb);
  }

  //------------------------------------------------------------------
  // Getters & Setters
  //------------------------------------------------------------------

  public int[] getDistributions() {
    return distributions;
  }

  public int getAvg() {
    return avg;
  }

  public int getMax() {
    return max;
  }

  public int getMin() {
    return min;
  }

  public int getRps() {
    return rps;
  }

  public LinkedList<Long> getRpsList() {
    return rpsList;
  }

  //------------------------------------------------------------------
  // Other Parts
  //------------------------------------------------------------------

  /**
   * An internal class to mark time. Just use the stop() to stop time.
   *
   * @author <a href="mailto:xiejiyun@gmail.com">Xie, Jiyun</a>
   * @version 1.0.0
   * @since 2012-8-14
   */
  public class Stop {
    private long startTime;

    /**
     * Create a stop class with current time as the start Time.
     */
    private Stop() {
      super();
      this.startTime = System.currentTimeMillis();
    }

    /**
     * Stop this time marker, and save the result into the mother Stop Watch of this object.
     */
    public void stop() {
      long time = System.currentTimeMillis() - startTime;
      linkList.add(new Integer((int) time));
      counter.incrementAndGet();
    }
  }
}
TOP

Related Classes of org.apache.niolex.commons.test.StopWatch$Stop

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.