From 3ee7acd137ffd4df6edcff788f9a75eb1f533ffc Mon Sep 17 00:00:00 2001 From: Bryce McKinlay Date: Sat, 10 Jul 2004 02:38:55 +0000 Subject: [PATCH] java.util.Calendar.java (cache): New private static field. 2004-07-09 Bryce McKinlay * java.util.Calendar.java (cache): New private static field. Cached mappings of locales->calendar classes. (ctorArgTypes): New private static field. Singleton argument for calendar class constructor lookup. (getInstance): Cache Locale->Calendar class mappings using HashMap. Optimize by bypassing reflection instantiation for the GregorianCalendar case. From-SVN: r84438 --- libjava/ChangeLog | 10 +++++ libjava/java/util/Calendar.java | 73 +++++++++++++++++++++++++-------- 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index c69302e425a..5e2492069c9 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,13 @@ +2004-07-09 Bryce McKinlay + + * java.util.Calendar.java (cache): New private static field. Cached + mappings of locales->calendar classes. + (ctorArgTypes): New private static field. Singleton argument for + calendar class constructor lookup. + (getInstance): Cache Locale->Calendar class mappings using HashMap. + Optimize by bypassing reflection instantiation for the + GregorianCalendar case. + 2004-07-09 Bryce McKinlay * java/util/Calendar.java: Use getSystemClassLoader as argument for diff --git a/libjava/java/util/Calendar.java b/libjava/java/util/Calendar.java index e1ecf3e519a..b7ffb338106 100644 --- a/libjava/java/util/Calendar.java +++ b/libjava/java/util/Calendar.java @@ -437,6 +437,16 @@ public abstract class Calendar implements Serializable, Cloneable return getInstance(TimeZone.getDefault(), locale); } + /** + * Cache of locale->calendar-class mappings. This avoids having to do a ResourceBundle + * lookup for every getInstance call. + */ + private static HashMap cache = new HashMap(); + + /** Preset argument types for calendar-class constructor lookup. */ + private static Class[] ctorArgTypes + = new Class[] {TimeZone.class, Locale.class}; + /** * Creates a calendar representing the actual time, using the given * time zone and locale. @@ -445,29 +455,58 @@ public abstract class Calendar implements Serializable, Cloneable */ public static synchronized Calendar getInstance(TimeZone zone, Locale locale) { - String calendarClassName = null; - ResourceBundle rb = getBundle(locale); - calendarClassName = rb.getString("calendarClass"); - if (calendarClassName != null) + Class calendarClass = (Class) cache.get(locale); + Throwable exception = null; + + try { - try + if (calendarClass == null) { - Class calendarClass = Class.forName(calendarClassName); - if (Calendar.class.isAssignableFrom(calendarClass)) + ResourceBundle rb = getBundle(locale); + String calendarClassName = rb.getString("calendarClass"); + + if (calendarClassName != null) { - return (Calendar) calendarClass.getConstructor( - new Class[] { TimeZone.class, Locale.class} - ).newInstance(new Object[] {zone, locale} ); + calendarClass = Class.forName(calendarClassName); + if (Calendar.class.isAssignableFrom(calendarClass)) + cache.put(locale, calendarClass); } } - catch (ClassNotFoundException ex) {} - catch (IllegalAccessException ex) {} - catch (NoSuchMethodException ex) {} - catch (InstantiationException ex) {} - catch (InvocationTargetException ex) {} - // XXX should we ignore these errors or throw an exception ? + + // GregorianCalendar is by far the most common case. Optimize by + // avoiding reflection. + if (calendarClass == GregorianCalendar.class) + return new GregorianCalendar(zone, locale); + + if (Calendar.class.isAssignableFrom(calendarClass)) + { + Constructor ctor = calendarClass.getConstructor(ctorArgTypes); + return (Calendar) ctor.newInstance(new Object[] {zone, locale}); + } + } + catch (ClassNotFoundException ex) + { + exception = ex; + } + catch (IllegalAccessException ex) + { + exception = ex; + } + catch (NoSuchMethodException ex) + { + exception = ex; + } + catch (InstantiationException ex) + { + exception = ex; + } + catch (InvocationTargetException ex) + { + exception = ex; } - return new GregorianCalendar(zone, locale); + + throw new RuntimeException("Error instantiating calendar for locale " + + locale, exception); } /** -- 2.30.2