1aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin/* GENERATED SOURCE. DO NOT MODIFY. */
2aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin/*
3aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin *******************************************************************************
4aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin * Copyright (C) 2011-2012, Google, International Business Machines Corporation and
5aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin * others. All Rights Reserved.
6aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin *******************************************************************************
7aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin */
8aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinpackage android.icu.dev.util;
9aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
10aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.text.DecimalFormat;
11aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.text.NumberFormat;
12aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.util.ULocale;
13aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
14aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinpublic final class Timer {
15aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public static final long SECONDS = 100000000;
16aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
17aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private long startTime;
18aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private long duration;
19aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private boolean timing = false;
20aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private int iterations;
21aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private long timingPeriod = 5*SECONDS;
22aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    {
23aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        start();
24aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
25aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
26aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public Timer start() {
27aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        startTime = System.nanoTime();
28aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        timing = true;
29aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        duration = Long.MIN_VALUE;
30aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return this;
31aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
32aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
33aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public long getDuration() {
34aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        if (timing) {
35aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            duration = System.nanoTime() - startTime;
36aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            timing = false;
37aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
38aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return duration;
39aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
40aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
41aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public long stop() {
42aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return getDuration();
43aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
44aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
45aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public int getIterations() {
46aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return iterations;
47aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
48aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
49aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public long getTimingPeriod() {
50aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return timingPeriod;
51aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
52aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
53aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public Timer setTimingPeriod(long timingPeriod) {
54aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        this.timingPeriod = timingPeriod;
55aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return this;
56aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
57aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
58aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public DecimalFormat getNumberFormat() {
59aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return nf;
60aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
61aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
62aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public DecimalFormat getPercentFormat() {
63aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return pf;
64aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
65aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
66aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public String toString() {
67aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return nf.format(getDuration()) + "\tns";
68aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
69aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public String toString(Timer other) {
70aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return toString(1L, other.getDuration());
71aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
72aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public String toString(long iterations) {
73aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return nf.format(getDuration()/iterations) + "\tns";
74aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
75aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
76aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public String toString(long iterations, long other) {
77aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return nf.format(getDuration()/iterations) + "\tns\t" + pf.format((double)getDuration()/other - 1D) + "";
78aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
79aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
80aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private DecimalFormat nf = (DecimalFormat) NumberFormat.getNumberInstance(ULocale.ENGLISH);
81aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private DecimalFormat pf = (DecimalFormat) NumberFormat.getPercentInstance(ULocale.ENGLISH);
82aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
83aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    {
84aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        pf.setMaximumFractionDigits(1);
85aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        pf.setPositivePrefix("+");
86aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
87aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
88aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public abstract static class Loop {
89aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        public void init(Object... params) {}
90aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        abstract public void time(int repeat);
91aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
92aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
93aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public long timeIterations(Loop loop, Object... params) {
94aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // Timing on Java is very tricky, especially when you count in garbage collection. This is a simple strategy for now, we might improve later.
95aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // The current strategy is to warm up once, then time it until we reach the timingPeriod (eg 5 seconds), increasing the iterations each time
96aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // At first, we double the iterations.
97aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // Once we get to within 1/4 of the timingPeriod, we change to adding 33%, plus 1. We also remember the shortest duration from this point on.
98aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // We return the shortest of the durations.
99aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        loop.init(params);
100aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        System.gc();
101aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        start();
102aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        loop.time(1);
103aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        stop();
104aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        iterations = 1;
105aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        long shortest = Long.MAX_VALUE;
106aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        while (true) {
107aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            System.gc();
108aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            start();
109aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            loop.time(iterations);
110aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            stop();
111aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            if (duration >= timingPeriod) {
112aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                duration /= iterations;
113aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                return Math.min(duration, shortest);
114aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            } else if (duration >= timingPeriod / 4) {
115aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                duration /= iterations;
116aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                shortest = Math.min(duration, shortest);
117aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                iterations = (iterations * 4) / 3 + 1;
118aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            } else {
119aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                iterations = iterations * 2;
120aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            }
121aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
122aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
123aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin}