JDK-7163865 : Performance improvement for DateFormatSymbols.getZoneIndex(String)
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.text
  • Affected Version: 7
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2012-04-24
  • Updated: 2013-06-26
  • Resolved: 2012-05-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8
7u40Fixed 8 b38Fixed
Description
A DESCRIPTION OF THE REQUEST :
The getZoneIndex() method is expensive and it's performance depends on which timezone you're in. This is because the code steps through a list of timezones until it finds the current one. This is happening over and over again. An idea would be to either cache it or rewrite the way we store time zone ids, such as a hashmap instead of an array.


JUSTIFICATION :
Applications which  format/parse dates using SimpleDateFormat repeatedly may obtain benefits from this patch, especially when run in a timezone far down the zoneStrings array the improvements will be even bigger.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
There is a test when when parse a string based on a time zone in the lower end of the zoneString array, the total time is about 742 ms.
ACTUAL -
With a cache, the total time could be reduced to about 460 ms.

---------- BEGIN SOURCE ----------
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.TimeZone;

import sun.util.TimeZoneNameUtility;

public class GetZoneIndexTest {

    /**
     * This test case intends to test the performance of
     * DateFormatSymbols.getZoneIndex(). Because it is not a public method, the
     * test case tests the performance of SimpleDateFormat.parse() which will
     * invokes the DateFormatSymbols.getZoneIndex().
     *
     * @param args
     * @throws ParseException
     */
    public static void main(String[] args) throws ParseException {
        String[][] timezones = TimeZoneNameUtility.getZoneStrings(Locale
                .getDefault());
        String lastZone = timezones[timezones.length - 1][0];

        DateFormat sdf = new SimpleDateFormat("yyyy.MM.dd zzzz");
        sdf.setTimeZone(TimeZone.getTimeZone(lastZone));

        // warm up
        for (int i = 0; i < 100; i++) {
            sdf.parse("2012.03.29 Coordinated Universal Time");
        }

        long time = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            sdf.parse("2012.03.29 Coordinated Universal Time");
        }
        time = System.currentTimeMillis() - time;

        System.out.println("The total time is " + time + " ms!");
    }
}
---------- END SOURCE ----------

Comments
EVALUATION The fix has been contributed by the community. The fix is to keep the last index matched.
01-05-2012