On Jul 18, 2007, at 23:18, Jeremias Maerki wrote:

Some additional thoughts before going to bed:

- I think the static synchronized WeakHashMap should be avoided. There's
a lot of synchronization that is performed. I suspect this will have a
bad effect on performance.

I have always assumed it would have some effect that could be interpreted as bad. Richard's initial version of the PropertyCache synchronized the fetch () method, and if I remember and interpret correctly, this caused a noticeable slowdown in performing the jUnit tests. Once I decided to use Collections.synchronizedMap(), the speed went back to normal.

It may make more sense to have a
FlyWeightFactory (per object) per rendering run. Somebody (don't
remember who, sorry) wrote that FOP cannot bring the CPU to 100%,
probably due to synchronization issues. Could be worth investigating
since this would mean we give away CPU cicles here.

Could indeed be interesting to know if it's really the synchronization or other aspects of FOP's architecture that would be the cause of that. Using statics and the above utility method of course makes performance greatly dependent on the cleverness of the JVM implementation. Other than that, /if/ any synchronization should be performed, then it would seem better to do so on the lower level: with the original patch, multiple calls to the fetch() method would be prevented from being executed concurrently, even if none of them altered the underlying Map.

- It's probably not the most effective way to use the Property itself as
the key into the Map, i.e. creating throw-away instances excessively.
Working with specialized FlyWeightFactories could be more efficient. See
http://en.wikipedia.org/wiki/Flyweight_pattern

Also my initial thought: if the Property is simply a wrapper around an int or a String, then I'd assume that it would be better to check for an existing instance corresponding to that base value. Then again, I do seem to remember Richard pointing out that creating a lot of temporary instances is quasi irrelevant in a language like Java, especially the later JVM versions. IIRC, it has to do with the fact that the throw-away instances never have to leave the stack -- which by itself already saves the time it takes to reserve addresses in the heap and transfer the instances to them.

This factor does become important once you have a situation where a pass through the constructor triggers a method call for each of a handful of members, like in the case of the Common-bundles. In case of the immediate Property subclasses, however, the constructors themselves are actually very light, so it should not be much of a problem. The bulk of the 'construction' work is carried by the Makers and the PropertyParser.

- One of the easiest candidates for another flyweight is probably
CommonHyphenation (56K instances, 2.3MB in my example). The few member
variables could probably just be concatenated to a String (to be used as
the key).

Interesting idea, will look into that asap.

- It could be worth looking into the difference between HashMap and
TreeMap. Maybe one is more suitable than the other. I haven't looked at
the difference, yet.

No idea here either. Come to think of it, I've never really looked at TreeMap before at all. I'd have to check for specific use-cases first to see what the specific use could be here. There's no WeakTreeMap yet, though... 8-)


Cheers

Andreas

Reply via email to