2 *******************************************************************************
3 * Copyright (C) 2011-2012, Google, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 *******************************************************************************
7 package com.ibm.icu.dev.util;
9 import com.ibm.icu.text.DecimalFormat;
10 import com.ibm.icu.text.NumberFormat;
11 import com.ibm.icu.util.ULocale;
13 public final class Timer {
14 public static final long SECONDS = 100000000;
16 private long startTime;
17 private long duration;
18 private boolean timing = false;
19 private int iterations;
20 private long timingPeriod = 5*SECONDS;
25 public Timer start() {
26 startTime = System.nanoTime();
28 duration = Long.MIN_VALUE;
32 public long getDuration() {
34 duration = System.nanoTime() - startTime;
44 public int getIterations() {
48 public long getTimingPeriod() {
52 public Timer setTimingPeriod(long timingPeriod) {
53 this.timingPeriod = timingPeriod;
57 public DecimalFormat getNumberFormat() {
61 public DecimalFormat getPercentFormat() {
65 public String toString() {
66 return nf.format(getDuration()) + "\tns";
68 public String toString(Timer other) {
69 return toString(1L, other.getDuration());
71 public String toString(long iterations) {
72 return nf.format(getDuration()/iterations) + "\tns";
75 public String toString(long iterations, long other) {
76 return nf.format(getDuration()/iterations) + "\tns\t" + pf.format((double)getDuration()/other - 1D) + "";
79 private DecimalFormat nf = (DecimalFormat) NumberFormat.getNumberInstance(ULocale.ENGLISH);
80 private DecimalFormat pf = (DecimalFormat) NumberFormat.getPercentInstance(ULocale.ENGLISH);
83 pf.setMaximumFractionDigits(1);
84 pf.setPositivePrefix("+");
87 public abstract static class Loop {
88 public void init(Object... params) {}
89 abstract public void time(int repeat);
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.
104 long shortest = Long.MAX_VALUE;
108 loop.time(iterations);
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;
118 iterations = iterations * 2;