JDK-4908648 : Performance problem in JDK 1.4 getting locales
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 1.1.4,6
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,solaris_8
  • CPU: generic
  • Submitted: 2003-08-19
  • Updated: 2013-11-01
  • Resolved: 2005-09-12
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 6
6 b52Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
---------------------------------------
java -version : 1.2.2
locale length 144
time to get locales 1340
-------------------------------------------
java -version 1.4.0
bash-2.03# java Test
locale length 148
time to get locales 5699
----------------------------------

import java.util.Locale;

public class Test {
        public static void main(String args[])  {
                long start = System.currentTimeMillis();
                Locale[] mLocale = Locale.getAvailableLocales();
                System.out.println("locale length " + mLocale.length);
                long end = System.currentTimeMillis();
                System.out.println("time to get locales " + (end-start));
        }
}

Comments
EVALUATION On Solaris8, 1.5.0b28 is slower than 1.4.2FCS. 1.2.2 locale length 144 time to get locales 1049 1.3.1 locale length 145 time to get locales 964 1.4.2 locale length 134 time to get locales 5014 1.5.0-b28 locale length 130 time to get locales 3797 Needs to be investigated. ###@###.### 2003-11-17 The above data is not very precise. I suspect some data it got was from the first run (actually when you switch from one jdk to another version of jdk, the first time, it runs a bit slower since the system may need to page in the new jar files etc). After several runs, the time I got from 1.4.2 is actually around 2.5 times longer than 1.3. Here is the investigation summary when I broke down the data. The main difference here is at Locale.getClassList (for 1.3.1, due to code reorganization, LocaleData.getClassList is doing the same thing in 1.4 or later). "getClassList" basically scans the jar files in the classpath ($jre/lib & $jre/lib/ext diectory) and look for LocaleElements_*.class from those jar files. Since I/O is involved, the more jar files containing LocaleElements_*, the slower this method runs. For JRE 1.3.1 or earlier, all the LocaleElements_*.class is in one jar file, i18n.jar. Also in 1.3.1, there is no jsse.jar, jce.jar. Since 1.4, we added 4 jar files under lib/ext directory and jsse.jar, jce.jar. Even though these jar files does not contain any LocaleElements related class files, they are scanned since we assume they may contain these locale sensitive data. Also since 1.4, we broke LocaleElements and other resources such as DateFormatZoneData into localeData.jar in extension directory and rt.jar. Another performance contribution factor is the size of each jar files scanned, since rt.jar was 13M in 1.3 and it jumped to 22M in 1.4 and it continues to grow since then. So probably one option to fix this is to limit the LocaleElements classes in one or more specific jar files and we only looks for those jar file. getAvailableLocales is usually called to iterate all the supported locales in JRE, not many people actually call it in performance sensitive code. So I am not convinced that we should change the current behavior unless we get many complaints about fixing this. Not sure fixing it will break some existing app which has already assumed this behavior even though they are not supposed to. ###@###.### 2005-04-21 01:35:40 GMT ###@###.### 2005-04-21 01:58:30 GMT Here is some performance data I got when measuring the following code execution called by "LocaleData.getClassList": ZipInputStream zipFile = new ZipInputStream(new FileInputStream(f)); ZipEntry entry; while ((entry = zipFile.getNextEntry()) != null) { String eName = entry.getName(); if (eName.startsWith(packagePath)) { if (eName.endsWith(".class")) { addClass(midString(eName, packagePath, ".class"), listBuffer, prefix); } } } The total time spending at Locale.getAvailableLocales is 1093 ms. The above code iterates all of the follwing jar files and next to it is the time spent in executing the above code: sunpkcs11.jar 26764904 sunjce_provider.jar 21577869 localedata.pack 765422 localedata.jar 17322613 dnsns.jar 1960176 rt.jar 838961489 jsse.jar 13794128 jce.jar 10294860 charsets.jar 138510353 The total time spent on rt.jar & charsets.jar takes 90% of the whole time. I filed an RFE for scan the jar file with a certain pattern like "sun.text.resource.LocaleElements_*". Currently the only way to scan the jar files for classes like that is to iterate all the entries and match ourselves. That is way too inefficient. ###@###.### 2005-04-21 21:02:17 GMT Minor correction: In 1.3.1, a few locale data resource bundles were located in rt.jar. In later releases, more bundles migrated from i18n.jar/localedata.jar to rt.jar, but the number of jar files housing locale data didn't change. 4061452, if implemented efficiently, might provide a better solution to the problem of finding all resource bundles of one family. Or, if an efficient implementation of getAvailableLocales turns out to be critical, we might go back to the original implementation, which had a static Locale[] directly initialized with a hand-crafted list of the locales for all JRE resource bundles in the code. ###@###.### 2005-04-21 21:52:24 GMT This performance bug will be addressed together with bug 6293734. The fix is to prebake a list of supported locales for sun.text.resources.FormatData during build time and contruct the Locale list using that list. This will speed up the method call significantly. ###@###.### 2005-07-20 01:09:26 GMT
20-07-2005