• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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.util;
18 
19 import java.util.ArrayList;
20 
21 import android.os.SystemClock;
22 
23 /**
24  * A utility class to help log timings splits throughout a method call.
25  * Typical usage is:
26  *
27  * TimingLogger timings = new TimingLogger(TAG, "methodA");
28  * ... do some work A ...
29  * timings.addSplit("work A");
30  * ... do some work B ...
31  * timings.addSplit("work B");
32  * ... do some work C ...
33  * timings.addSplit("work C");
34  * timings.dumpToLog();
35  *
36  * The dumpToLog call would add the following to the log:
37  *
38  * D/TAG     ( 3459): methodA: begin
39  * D/TAG     ( 3459): methodA:      9 ms, work A
40  * D/TAG     ( 3459): methodA:      1 ms, work B
41  * D/TAG     ( 3459): methodA:      6 ms, work C
42  * D/TAG     ( 3459): methodA: end, 16 ms
43  */
44 public class TimingLogger {
45 
46     /**
47      * The Log tag to use for checking Log.isLoggable and for
48      * logging the timings.
49      */
50     private String mTag;
51 
52     /** A label to be included in every log. */
53     private String mLabel;
54 
55     /** Used to track whether Log.isLoggable was enabled at reset time. */
56     private boolean mDisabled;
57 
58     /** Stores the time of each split. */
59     ArrayList<Long> mSplits;
60 
61     /** Stores the labels for each split. */
62     ArrayList<String> mSplitLabels;
63 
64     /**
65      * Create and initialize a TimingLogger object that will log using
66      * the specific tag. If the Log.isLoggable is not enabled to at
67      * least the Log.VERBOSE level for that tag at creation time then
68      * the addSplit and dumpToLog call will do nothing.
69      * @param tag the log tag to use while logging the timings
70      * @param label a string to be displayed with each log
71      */
TimingLogger(String tag, String label)72     public TimingLogger(String tag, String label) {
73         reset(tag, label);
74     }
75 
76     /**
77      * Clear and initialize a TimingLogger object that will log using
78      * the specific tag. If the Log.isLoggable is not enabled to at
79      * least the Log.VERBOSE level for that tag at creation time then
80      * the addSplit and dumpToLog call will do nothing.
81      * @param tag the log tag to use while logging the timings
82      * @param label a string to be displayed with each log
83      */
reset(String tag, String label)84     public void reset(String tag, String label) {
85         mTag = tag;
86         mLabel = label;
87         reset();
88     }
89 
90     /**
91      * Clear and initialize a TimingLogger object that will log using
92      * the tag and label that was specified previously, either via
93      * the constructor or a call to reset(tag, label). If the
94      * Log.isLoggable is not enabled to at least the Log.VERBOSE
95      * level for that tag at creation time then the addSplit and
96      * dumpToLog call will do nothing.
97      */
reset()98     public void reset() {
99         mDisabled = !Log.isLoggable(mTag, Log.VERBOSE);
100         if (mDisabled) return;
101         if (mSplits == null) {
102             mSplits = new ArrayList<Long>();
103             mSplitLabels = new ArrayList<String>();
104         } else {
105             mSplits.clear();
106             mSplitLabels.clear();
107         }
108         addSplit(null);
109     }
110 
111     /**
112      * Add a split for the current time, labeled with splitLabel. If
113      * Log.isLoggable was not enabled to at least the Log.VERBOSE for
114      * the specified tag at construction or reset() time then this
115      * call does nothing.
116      * @param splitLabel a label to associate with this split.
117      */
addSplit(String splitLabel)118     public void addSplit(String splitLabel) {
119         if (mDisabled) return;
120         long now = SystemClock.elapsedRealtime();
121         mSplits.add(now);
122         mSplitLabels.add(splitLabel);
123     }
124 
125     /**
126      * Dumps the timings to the log using Log.d(). If Log.isLoggable was
127      * not enabled to at least the Log.VERBOSE for the specified tag at
128      * construction or reset() time then this call does nothing.
129      */
dumpToLog()130     public void dumpToLog() {
131         if (mDisabled) return;
132         Log.d(mTag, mLabel + ": begin");
133         final long first = mSplits.get(0);
134         long now = first;
135         for (int i = 1; i < mSplits.size(); i++) {
136             now = mSplits.get(i);
137             final String splitLabel = mSplitLabels.get(i);
138             final long prev = mSplits.get(i - 1);
139 
140             Log.d(mTag, mLabel + ":      " + (now - prev) + " ms, " + splitLabel);
141         }
142         Log.d(mTag, mLabel + ": end, " + (now - first) + " ms");
143     }
144 }
145