JDK-4209900 : Using ResourceBundle.getBundle() kills performance
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 1.1.5
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_nt
  • CPU: x86
  • Submitted: 1999-02-09
  • Updated: 2013-11-01
  • Resolved: 1999-06-26
Related Reports
Duplicate :  
Relates :  
Description

Name: gsC80088			Date: 02/08/99


Just use ResourceBundle.getBundle() often in an
application.  My application spent 50% of its
time looking up the ClassLoader, even when the
contents of the resource were cached.
(Review ID: 29104)
======================================================================

Comments
WORK AROUND Name: gsC80088 Date: 02/08/99 Manually cache the ResourceBundle you get from ResourceBundle.getBundle() with a class variable. ======================================================================
11-06-2004

EVALUATION Can similar problems be observed in other applications, or is this an extreme case? Please investigate. norbert.lindenberg@Eng 1999-04-12 ResourceBundle has been sped up substantially for Kestrel, but the issue mentioned here (getting ClassLoader) didn't show up as a major contributing factor. It's possible that this depends on whether code is run in a trusted or untrusted environment - this still needs to be investigated. norbert.lindenberg@Eng 1999-06-08 I tried with the following test case and the current awt.properties file: import java.util.Locale; import java.util.ResourceBundle; public class ResPerf { public static void main(String[] args) { ResourceBundle bundle; long startTime; ClassLoader loader; startTime = System.currentTimeMillis(); bundle = ResourceBundle.getBundle("awt", Locale.US); System.out.println("first load: " + (System.currentTimeMillis() - startTime) + "ms"); startTime = System.currentTimeMillis(); for (int i = 0; i < 1000; i++) { bundle = ResourceBundle.getBundle("awt", Locale.US); } System.out.println("1000 loads with class loader lookup: " + (System.currentTimeMillis() - startTime) + "ms"); loader = ResPerf.class.getClassLoader(); startTime = System.currentTimeMillis(); for (int i = 0; i < 1000; i++) { bundle = ResourceBundle.getBundle("awt", Locale.US, loader); } System.out.println("1000 loads with specified class loader: " + (System.currentTimeMillis() - startTime) + "ms"); } } I ran this app with and without -Djava.security.manager on the Kestrel-I build, which has the performance improvements mentioned above. Results: $ javasp ResPerf first load: 180ms 1000 loads with class loader lookup: 118ms 1000 loads with specified class loader: 119ms $ java -Djava.security.manager ResPerf first load: 231ms 1000 loads with class loader lookup: 118ms 1000 loads with specified class loader: 115ms These numbers don't support the notion that class loader lookup is a major performance bottleneck. For comparison, here are the numbers for 1.2: $ java12 ResPerf first load: 119ms 1000 loads with class loader lookup: 5137ms 1000 loads with specified class loader: 5088ms $ java12 -Djava.security.manager ResPerf first load: 163ms 1000 loads with class loader lookup: 10459ms 1000 loads with specified class loader: 10259ms This demonstrates the significant improvements made in the caching algorithm under bug 4168625. I think the improvements are sufficient that we can consider this bug a duplicate of 4168625. norbert.lindenberg@Eng 1999-06-25
25-06-1999