package com.tspoon.benchit; import android.util.Log; import android.util.Pair; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; public class Benchit { public static final String TAG = "Benchit"; static Benchit.Precision DEFAULT_PRECISION = Benchit.Precision.MILLI; static Set<Stat> STATISTICS = new HashSet<>(); private static Benchit singleton; private HashMap<String, Long> starts; private HashMap<String, Benchmark> benchmarks; Benchit() { starts = new HashMap<>(); benchmarks = new HashMap<>(); Benchit.setEnabledStats(Stat.AVERAGE, Stat.RANGE, Stat.STANDARD_DEVIATION); } private static Benchit get() { if (singleton == null) { singleton = new Benchit(); } return singleton; } public static Benchit begin(String tag) { if (singleton == null) { singleton = get(); } return singleton.beginInternal(tag); } public static Benchmark end(String tag) { if (singleton == null) { singleton = get(); } return singleton.endInternal(tag); } public static Result analyze(String tag) { if (singleton == null) { singleton = get(); } return singleton.analyzeInternal(tag); } public static Benchit clear() { if (singleton == null) { singleton = get(); } return singleton.clearInternal(); } public static ComparisonResult compare(Stat orderBy, Order order, String... tags) { if (singleton == null) { singleton = get(); } return singleton.compareInternal(orderBy, order, tags); } public static ComparisonResult compare(Stat orderBy, String... tags) { return compare(orderBy, Order.ASCENDING, tags); } public static void setDefaultPrecision(Precision precision) { if (precision != null) { DEFAULT_PRECISION = precision; } } public static void setEnabledStats(Stat... stats) { STATISTICS = new HashSet<>(); Collections.addAll(STATISTICS, stats); } private Benchit beginInternal(String tag) { starts.put(tag, System.nanoTime()); return this; } private Benchmark endInternal(String tag) { long end = System.nanoTime(); long start = starts.get(tag); long taken = end - start; Benchmark benchmark = benchmarks.get(tag); if (benchmark == null) { benchmark = new Benchmark(tag, taken); benchmarks.put(tag, benchmark); } else { benchmark.add(taken); } return benchmark; } private Result analyzeInternal(String tag) { Benchmark benchmark = benchmarks.get(tag); return benchmark.result(); } private Benchit clearInternal() { starts.clear(); benchmarks.clear(); return this; } private ComparisonResult compareInternal(Stat orderBy, Order order, String... tags) { ArrayList<Result> results = new ArrayList<>(); if (tags.length == 0) { for (String tag : benchmarks.keySet()) { results.add(analyzeInternal(tag)); } } else { for (String tag : tags) { results.add(analyzeInternal(tag)); } } return new ComparisonResult(orderBy, order, results); } static void log(String message) { Log.d(TAG, message); } static void log(String type, String tag, String result) { String log = String.format("%s [%s] --> %s", type, tag, result); Log.d(TAG, log); } static void logMany(String tag, List<Pair<String, String>> stats) { StringBuilder sb = new StringBuilder("[" + tag + "] --> "); for (Pair<String, String> stat : stats) { sb.append(String.format("%s[%s], ", stat.first, stat.second)); } sb.delete(sb.length() - 2, sb.length() - 1); Log.d(TAG, sb.toString()); } public static enum Stat { AVERAGE, RANGE, STANDARD_DEVIATION } public static enum Order { ASCENDING, DESCENDING } public static enum Precision { NANO("ns", 1), MICRO("µs", 1000), MILLI("ms", 1000000), SECOND("s", 1000000000); String unit; int divider; Precision(String unit, int divider) { this.unit = unit; this.divider = divider; } } }