1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.os; 18 19 import android.util.Log; 20 21 import java.util.HashMap; 22 23 /** 24 * A class to help with measuring latency in your code. 25 * 26 * Suggested usage: 27 * 1) Instanciate a LatencyTimer as a class field. 28 * private [static] LatencyTimer mLt = new LatencyTimer(100, 1000); 29 * 2) At various points in the code call sample with a string and the time delta to some fixed time. 30 * The string should be unique at each point of the code you are measuring. 31 * mLt.sample("before processing event", System.nanoTime() - event.getEventTimeNano()); 32 * processEvent(event); 33 * mLt.sample("after processing event ", System.nanoTime() - event.getEventTimeNano()); 34 * 35 * @hide 36 */ 37 public final class LatencyTimer 38 { 39 final String TAG = "LatencyTimer"; 40 final int mSampleSize; 41 final int mScaleFactor; 42 volatile HashMap<String, long[]> store = new HashMap<String, long[]>(); 43 44 /** 45 * Creates a LatencyTimer object 46 * @param sampleSize number of samples to collect before printing out the average 47 * @param scaleFactor divisor used to make each sample smaller to prevent overflow when 48 * (sampleSize * average sample value)/scaleFactor > Long.MAX_VALUE 49 */ 50 public LatencyTimer(int sampleSize, int scaleFactor) { 51 if (scaleFactor == 0) { 52 scaleFactor = 1; 53 } 54 mScaleFactor = scaleFactor; 55 mSampleSize = sampleSize; 56 } 57 58 /** 59 * Add a sample delay for averaging. 60 * @param tag string used for printing out the result. This should be unique at each point of 61 * this called. 62 * @param delta time difference from an unique point of reference for a particular iteration 63 */ 64 public void sample(String tag, long delta) { 65 long[] array = getArray(tag); 66 67 // array[mSampleSize] holds the number of used entries 68 final int index = (int) array[mSampleSize]++; 69 array[index] = delta; 70 if (array[mSampleSize] == mSampleSize) { 71 long totalDelta = 0; 72 for (long d : array) { 73 totalDelta += d/mScaleFactor; 74 } 75 array[mSampleSize] = 0; 76 Log.i(TAG, tag + " average = " + totalDelta / mSampleSize); 77 } 78 } 79 80 private long[] getArray(String tag) { 81 long[] data = store.get(tag); 82 if (data == null) { 83 synchronized(store) { 84 data = store.get(tag); 85 if (data == null) { 86 data = new long[mSampleSize + 1]; 87 store.put(tag, data); 88 data[mSampleSize] = 0; 89 } 90 } 91 } 92 return data; 93 } 94 } 95