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