• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     */
LatencyTimer(int sampleSize, int scaleFactor)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      */
sample(String tag, long delta)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 
getArray(String tag)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