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