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