Hi i18n-devs,
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.
This patch[1] is for the cache option.
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.
I have written a test case[2] which shows when a timezone which is in
lower end of the zone strings array, the performance improvement this
patch can get.
test results:
no patch:
The total time is 742 ms!
with this patch[1] :
The total time is 508 ms!
If increase the loop times to 1000000, the results are:
no patch:
The total time is 4743 ms!
with this patch[1] :
The total time is 2126 ms!
The java version is:
/home/deven/hgrps/jdk8/build/linux-i586/j2sdk-image/bin/java -version
openjdk version "1.8.0-internal"
OpenJDK Runtime Environment (build
1.8.0-internal-deven_2012_03_14_16_14-b00)
OpenJDK Server VM (build 24.0-b02, mixed mode)
[1] http://cr.openjdk.java.net/~youdwei/DateFormatSymbol_perf/webrev.00/
<http://cr.openjdk.java.net/%7Eyoudwei/DateFormatSymbol_perf/webrev.00/>
[2] GetZoneIndexTest.java
/*
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Portions Copyright (c) 2012 IBM Corporation
*/
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!");
}
}