Bug 17700 - Performance issue in Resources.getMessage
Summary: Performance issue in Resources.getMessage
Status: RESOLVED WONTFIX
Alias: None
Product: Taglibs
Classification: Unclassified
Component: Standard Taglib (show other bugs)
Version: 1.1
Hardware: Other other
: P3 enhancement (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-03-05 23:18 UTC by Nick Coleman
Modified: 2009-08-17 02:03 UTC (History)
1 user (show)



Attachments
pre-parsed formats cached with simple pooling code (6.88 KB, patch)
2003-03-06 15:20 UTC, Nick Coleman
Details | Diff
CVS diff file containing changes made in previous upload (2.41 KB, patch)
2003-03-06 22:13 UTC, Nick Coleman
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Coleman 2003-03-05 23:18:00 UTC
Resources.getMessage takes 4 times as long as necessary because it calls the 
static function MessageFormat.format()

This function essentially instantiates a new MessageFormat object every time 
and then formats a message.  With each new instantiation, the message string 
must be parsed.

Using a profiling tool, I made 18,000 consecutive calls to the 
ResourceMessages.getMessage(String, Object[]) function on my machine which took 
49,340ms to process.  47,695ms was consumed in the MessageFormat.format() 
function.

I altered the class and created a static hashtable to cache MessageFormats 
after each initial request.  The formats were re-used instead of parsing the 
string with each call.  Making the same number of call to 
ResourceMessages.getMessage took only 10,086ms.

This is a simple alteration, below is the code I used to make this change.

    private static Hashtable formats = new Hashtable();
    private static MessageFormat getFormat(String name)
        throws MissingResourceException {
        MessageFormat format = (MessageFormat) formats.get(name);
        if (format==null) {
            format = new MessageFormat(rb.getString(name));
            formats.put(name, format);
        }
        return format;
    }

    /** Retrieves a message with arbitrarily many arguments. */
    public static String getMessage(String name, Object[] a)
	    throws MissingResourceException {
        Format f = getFormat(name);
        synchronized(f) {
            return f.format(a);
        }
    }
Comment 1 Nick Coleman 2003-03-06 15:20:20 UTC
Created attachment 5182 [details]
pre-parsed formats cached with simple pooling code
Comment 2 Nick Coleman 2003-03-06 22:13:30 UTC
Created attachment 5189 [details]
CVS diff file containing changes made in previous upload
Comment 3 Pierre Delisle 2003-08-26 22:36:21 UTC
Thanks for the suggestion on improving performance.

However, wouldn't we want a more sophisticated caching mechanism
to avoid having the cache grow indefinitely?
Comment 4 Felipe Leme 2004-05-12 00:27:00 UTC
CC'ing the taglibs-dev address to all Standard bugs. 
Comment 5 Henri Yandell 2007-02-07 17:33:26 UTC
SPI style plugin cache added for this (see attachment to issue
https://issues.apache.org/bugzilla/show_bug.cgi?id=31789 ).
Comment 6 Henri Yandell 2007-08-24 09:12:31 UTC
Quite a confusing issue.

As far as I can tell, the only things that use the Resources class are errors.
So there shouldn't be such a speed improvement unless Resources was being used
in the application too (ill advised I think) or there were lots of errors, in
which case there's a bigger issue.

There is no ResourcesMessages class in the JSTL implementation.

A cache could be put in place for the fmt:message, but it would need to be keyed
on both locale and pattern and I'm hesistant to dive in on that.

I think this should be a WONTFIX.