/* * Copyright 2008-2013, ETH Zürich, Samuel Welten, Michael Kuhn, Tobias Langner, * Sandro Affentranger, Lukas Bossard, Michael Grob, Rahul Jain, * Dominic Langenegger, Sonia Mayor Alonso, Roger Odermatt, Tobias Schlueter, * Yannick Stucki, Sebastian Wendland, Samuel Zehnder, Samuel Zihlmann, * Samuel Zweifel * * This file is part of Jukefox. * * Jukefox is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or any later version. Jukefox is * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * Jukefox. If not, see <http://www.gnu.org/licenses/>. */ /* * Copyright (C) 2007 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 ch.ethz.dcg.jukefox.commons.utils; import java.util.ArrayList; /** * A utility class to help log timings splits throughout a method call. Typical usage is: * * TimingLogger timings = new TimingLogger(TAG, "methodA"); ... do some work A ... timings.addSplit("work A"); ... do * some work B ... timings.addSplit("work B"); ... do some work C ... timings.addSplit("work C"); timings.dumpToLog(); * * The dumpToLog call would add the following to the log: * * D/TAG ( 3459): methodA: begin D/TAG ( 3459): methodA: 9 ms, work A D/TAG ( 3459): methodA: 1 ms, work B D/TAG ( * 3459): methodA: 6 ms, work C D/TAG ( 3459): methodA: end, 16 ms */ public class TimingLogger { /** * The Log tag to use for checking Log.isLoggable and for logging the timings. */ private String mTag; /** A label to be included in every log. */ private String mLabel; /** Stores the time of each split. */ ArrayList<Long> mSplits; /** Stores the labels for each split. */ ArrayList<String> mSplitLabels; /** * Create and initialize a TimingLogger object that will log using the specific tag. If the Log.isLoggable is not * enabled to at least the Log.VERBOSE level for that tag at creation time then the addSplit and dumpToLog call will * do nothing. * * @param tag * the log tag to use while logging the timings * @param label * a string to be displayed with each log */ public TimingLogger(String tag, String label) { reset(tag, label); } /** * Clear and initialize a TimingLogger object that will log using the specific tag. If the Log.isLoggable is not * enabled to at least the Log.VERBOSE level for that tag at creation time then the addSplit and dumpToLog call will * do nothing. * * @param tag * the log tag to use while logging the timings * @param label * a string to be displayed with each log */ public void reset(String tag, String label) { mTag = tag; mLabel = label; reset(); } /** * Clear and initialize a TimingLogger object that will log using the tag and label that was specified previously, * either via the constructor or a call to reset(tag, label). If the Log.isLoggable is not enabled to at least the * Log.VERBOSE level for that tag at creation time then the addSplit and dumpToLog call will do nothing. */ public void reset() { if (mSplits == null) { mSplits = new ArrayList<Long>(); mSplitLabels = new ArrayList<String>(); } else { mSplits.clear(); mSplitLabels.clear(); } addSplit(null); } /** * Add a split for the current time, labeled with splitLabel. If Log.isLoggable was not enabled to at least the * Log.VERBOSE for the specified tag at construction or reset() time then this call does nothing. * * @param splitLabel * a label to associate with this split. */ public void addSplit(String splitLabel) { long now = System.nanoTime() / 1000 / 1000; // ns -> ms mSplits.add(now); mSplitLabels.add(splitLabel); } /** * Dumps the timings to the log using Log.d(). If Log.isLoggable was not enabled to at least the Log.VERBOSE for the * specified tag at construction or reset() time then this call does nothing. */ public void dumpToLog() { Log.d(mTag, mLabel + ": begin"); final long first = mSplits.get(0); long now = first; for (int i = 1; i < mSplits.size(); i++) { now = mSplits.get(i); final String splitLabel = mSplitLabels.get(i); final long prev = mSplits.get(i - 1); Log.d(mTag, mLabel + ": " + (now - prev) + " ms, " + splitLabel); } Log.d(mTag, mLabel + ": end, " + (now - first) + " ms"); } }