blob: 5a4a512c283b2a287f8d513c1a5cc3c067f45ecd [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.util;
18
19import java.util.ArrayList;
20
21import android.os.SystemClock;
22
23/**
24 * A utility class to help log timings splits throughout a method call.
25 * Typical usage is:
26 *
Chet Haase49afa5b2010-08-23 11:39:53 -070027 * <pre>
28 * TimingLogger timings = new TimingLogger(TAG, "methodA");
29 * // ... do some work A ...
30 * timings.addSplit("work A");
31 * // ... do some work B ...
32 * timings.addSplit("work B");
33 * // ... do some work C ...
34 * timings.addSplit("work C");
35 * timings.dumpToLog();
36 * </pre>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037 *
Chet Haase49afa5b2010-08-23 11:39:53 -070038 * <p>The dumpToLog call would add the following to the log:</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039 *
Chet Haase49afa5b2010-08-23 11:39:53 -070040 * <pre>
41 * D/TAG ( 3459): methodA: begin
42 * D/TAG ( 3459): methodA: 9 ms, work A
43 * D/TAG ( 3459): methodA: 1 ms, work B
44 * D/TAG ( 3459): methodA: 6 ms, work C
45 * D/TAG ( 3459): methodA: end, 16 ms
46 * </pre>
Charles Munger81c262b2019-11-18 10:51:17 -080047 *
48 * @deprecated Use {@link android.os.Trace}, or
49 * <a href="https://developer.android.com/studio/profile/benchmark">Android Studio</a>. In
50 * general, milliseconds is the wrong granularity for method-level tracing. Rounding errors
51 * can overemphasize cheap operations, or underemphasize repeated operations. This timing
52 * system also does not take CPU scheduling or frequency into account.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053 */
Charles Munger81c262b2019-11-18 10:51:17 -080054@Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055public class TimingLogger {
56
57 /**
58 * The Log tag to use for checking Log.isLoggable and for
59 * logging the timings.
60 */
61 private String mTag;
62
63 /** A label to be included in every log. */
64 private String mLabel;
65
66 /** Used to track whether Log.isLoggable was enabled at reset time. */
67 private boolean mDisabled;
68
69 /** Stores the time of each split. */
70 ArrayList<Long> mSplits;
71
72 /** Stores the labels for each split. */
73 ArrayList<String> mSplitLabels;
74
75 /**
76 * Create and initialize a TimingLogger object that will log using
77 * the specific tag. If the Log.isLoggable is not enabled to at
78 * least the Log.VERBOSE level for that tag at creation time then
79 * the addSplit and dumpToLog call will do nothing.
80 * @param tag the log tag to use while logging the timings
81 * @param label a string to be displayed with each log
82 */
83 public TimingLogger(String tag, String label) {
84 reset(tag, label);
85 }
86
87 /**
88 * Clear and initialize a TimingLogger object that will log using
89 * the specific tag. If the Log.isLoggable is not enabled to at
90 * least the Log.VERBOSE level for that tag at creation time then
91 * the addSplit and dumpToLog call will do nothing.
92 * @param tag the log tag to use while logging the timings
93 * @param label a string to be displayed with each log
94 */
95 public void reset(String tag, String label) {
96 mTag = tag;
97 mLabel = label;
98 reset();
99 }
100
101 /**
102 * Clear and initialize a TimingLogger object that will log using
103 * the tag and label that was specified previously, either via
104 * the constructor or a call to reset(tag, label). If the
105 * Log.isLoggable is not enabled to at least the Log.VERBOSE
106 * level for that tag at creation time then the addSplit and
107 * dumpToLog call will do nothing.
108 */
109 public void reset() {
110 mDisabled = !Log.isLoggable(mTag, Log.VERBOSE);
111 if (mDisabled) return;
112 if (mSplits == null) {
113 mSplits = new ArrayList<Long>();
114 mSplitLabels = new ArrayList<String>();
115 } else {
116 mSplits.clear();
117 mSplitLabels.clear();
118 }
119 addSplit(null);
120 }
121
122 /**
123 * Add a split for the current time, labeled with splitLabel. If
124 * Log.isLoggable was not enabled to at least the Log.VERBOSE for
125 * the specified tag at construction or reset() time then this
126 * call does nothing.
127 * @param splitLabel a label to associate with this split.
128 */
129 public void addSplit(String splitLabel) {
130 if (mDisabled) return;
131 long now = SystemClock.elapsedRealtime();
132 mSplits.add(now);
133 mSplitLabels.add(splitLabel);
134 }
135
136 /**
137 * Dumps the timings to the log using Log.d(). If Log.isLoggable was
138 * not enabled to at least the Log.VERBOSE for the specified tag at
139 * construction or reset() time then this call does nothing.
140 */
141 public void dumpToLog() {
142 if (mDisabled) return;
143 Log.d(mTag, mLabel + ": begin");
144 final long first = mSplits.get(0);
145 long now = first;
146 for (int i = 1; i < mSplits.size(); i++) {
147 now = mSplits.get(i);
148 final String splitLabel = mSplitLabels.get(i);
149 final long prev = mSplits.get(i - 1);
150
151 Log.d(mTag, mLabel + ": " + (now - prev) + " ms, " + splitLabel);
152 }
153 Log.d(mTag, mLabel + ": end, " + (now - first) + " ms");
154 }
155}