diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/Timer.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/Timer.java index 943f5e06f0..474e70beab 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/Timer.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/Timer.java @@ -81,12 +81,18 @@ public final class Timer { } public long timeIterations(Loop loop, Object... params) { + // Timing on Java is very tricky, especially when you count in garbage collection. This is a simple strategy for now, we might improve later. + // The current strategy is to warm up once, then time it until we reach the timingPeriod (eg 5 seconds), increasing the iterations each time + // At first, we double the iterations. + // 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. + // We return the shortest of the durations. loop.init(params); System.gc(); start(); loop.time(1); stop(); - iterations = 2; + iterations = 1; + long shortest = Long.MAX_VALUE; while (true) { System.gc(); start(); @@ -94,9 +100,14 @@ public final class Timer { stop(); if (duration >= timingPeriod) { duration /= iterations; - return duration; + return Math.min(duration, shortest); + } else if (duration >= timingPeriod / 4) { + duration /= iterations; + shortest = Math.min(duration, shortest); + iterations = (iterations * 4) / 3 + 1; + } else { + iterations = iterations * 2; } - iterations <<= 1; } } } \ No newline at end of file diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/TrieMapTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/TrieMapTest.java index 7a126f284e..05fc3c91fc 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/TrieMapTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/TrieMapTest.java @@ -45,10 +45,12 @@ public class TrieMapTest extends TestFmwk { super.init(); if (unicodeTestMap.size() == 0) { if (getInclusion() < 5) { - logln("\tSmall version:\t to get more accurate figures and test for reasonable times, use -e5 or more"); + logln("\tShort version, timing for 1s:\t to get more accurate figures and test for reasonable times, use -e5 or more"); t.setTimingPeriod(1*Timer.SECONDS); } else { - t.setTimingPeriod((getInclusion() - 4)*Timer.SECONDS); + int seconds = getInclusion(); + logln("\tExhaustive version, timing for " + seconds + "s"); + t.setTimingPeriod(seconds*Timer.SECONDS); useSmallList = false; }