blob: ed2f0f9e3eff2fb92d6ca6dd531b6f8288072069 [file] [log] [blame]
Michael Chan53071d62009-05-13 17:29:48 -07001/*
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
17package android.os;
18
19import android.util.Log;
20
21import 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 */
37public 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}