package at.favre.lib.dali.builder; import android.util.Log; import java.util.ArrayList; import java.util.List; import at.favre.lib.dali.util.BenchmarkUtil; /** * A simple Profiler that helps in measuring parts of code. * * This will use nano seconds (if possible with SDK) */ public class PerformanceProfiler { private final static String TAG = PerformanceProfiler.class.getSimpleName(); private String description; private List<Duration> durations; private boolean isActivated; public PerformanceProfiler(String description) { this(description,true); } /** * @param description describes the task * @param isActivated if this is false, every call to a method will do exactly nothing to * avoid to have unnecessary overhead */ public PerformanceProfiler(String description, boolean isActivated) { this.description = description; this.durations = new ArrayList<Duration>(); this.isActivated = isActivated; } /** * Start a task. The id is needed to end the task * @param id * @param taskName */ public void startTask(int id, String taskName) { if(isActivated) { durations.add(new Duration(id, taskName, BenchmarkUtil.elapsedRealTimeNanos())); } } public void endTask(int id) { endTask(id,null); } public void endTask(int id,String additionalInfo) { if(isActivated) { for (Duration duration : durations) { if (duration.getId() == id) { duration.setEndTimstamp(BenchmarkUtil.elapsedRealTimeNanos()); if (additionalInfo != null) { duration.setAdditionalInfo(additionalInfo); } return; } } Log.w(TAG, "Could not find task with id " + id); } } /** * Returns the duration of the measured tasks in ms */ public double getDurationMs() { double durationMs = 0; for (Duration duration : durations) { if(duration.taskFinished()) { durationMs += duration.getDurationMS(); } } return durationMs; } public void printResultToLog(String tag) { if(isActivated) { StringBuilder sb = new StringBuilder("->\nLog profile for task " + description+" - "+ BenchmarkUtil.formatNum(getDurationMs(),"0.##")+"ms\n----------------------------------------\n"); for (Duration duration : durations) { String logMsg = " * "+duration.getTaskDescription(); if(duration.getAdditionalInfo() != null && !duration.getAdditionalInfo().isEmpty()) { logMsg += " / "+duration.getAdditionalInfo(); } if(duration.taskFinished()) { logMsg += " - " + BenchmarkUtil.formatNum(duration.getDurationMS(),"0.##") + "ms"; } else { logMsg += " - unfinished"; } sb.append(logMsg+"\n"); } Log.d(tag, sb.toString()); } } public void printResultToLog() { printResultToLog(TAG); } public static class Duration { private int id; private String taskDescription; private String additionalInfo; private long startTimestamp; private long duration=-1; public Duration(int id, String taskDescription, long startTimestamp) { this.id = id; this.taskDescription = taskDescription; this.startTimestamp = startTimestamp; } public String getAdditionalInfo() { return additionalInfo; } public void setAdditionalInfo(String additionalInfo) { this.additionalInfo = additionalInfo; } public void setEndTimstamp(long endTimstamp) { duration = endTimstamp - startTimestamp; } public long getDuration() { return duration; } public double getDurationMS() { return duration / 1000000d; } public boolean taskFinished() { return duration != -1; } public String getTaskDescription() { return taskDescription; } public int getId() { return id; } } }