Wojtek said:
So this small page has 15 language elements, so 15 calls to the HashMap.
The HasMap is the single most used part of the entire app. [...]
So yes, I have spent a little time trying to make it faster.
Silly question, but have you profiled it and found it to be "slow"? Or,
put another way, take up significant proportion of the overall CPU time
used to process a page request from start to finish?-- and is your
server actually strapped for CPU time? For the sake of argument, let's
say rendering a page takes 50 lookups and you get 20 page requests
per second, that's still "only" 1000 lookups per second. Unless you're
running your web server on a ZX Spectrum (and if you're getting a
serious volume of requests, you're probably using something reasonably
beefy in the first place...), this is probably a blip on the
horizon. And if in the meantime you're doing some I/O, database requests
etc, you may as well give your CPUs something to do while they're
waiting...
That said... there may be a possible improvement if the strings you're
currently looking up are *dynamic*. That is if you're doing something
like:
message = messages.get(languageCode + "menu");
In this case, there may be a slight performance gain in changing things
so that you always look up *static* strings. So you start with a map-
of-maps:
Map<String,Map<String,String>> messagesByCountry =
new HashMap<String,new IdentityHashMap<String,String>>;
Then when serving a page, you do one initial lookup to get the map for
your language, and after that, your keys are static strings:
Map<String,String> messages = messagesByCountry.get(langCode);
...
String menuStr = messages.get("menu");
If your strings are all static, you can use an IdentityHashMap (not
actually sure if this will give much gain since your static strings will
have cached hash codes anyway, and IIRC String.equals() tests for
object equality as the first test). If the keys that you're using to
*populate* the map at startup aren't static (i.e. not "embedded" in
the source code but read from a file etc), in any case
remember to call intern() on key string and put the interned version
into the map -- this way you will be literally putting in the same
String object as the one you later use to look up, and the equality
test will be fast.
I think it would be a horrid design for not much gain, but you could
also have a map of language code to array-of-strings, and have each
message type have a known position in the array. Probably not worth
doing unless you really *are* running your server on a ZX Spectrum,
though.
I repeat, though: if you haven't profiled your code and found the hash
map gets to actually be significant, you may risk putting a lot of work
in changing your code for no tangible gain.
Neil