Some time ago I had suggested eliminating FlexibleStringExpander
instances and just use the expandString(...) static method instead.
David pointed out that the FlexibleStringExpander instances perform some
pre-parsing of the expression during construction to make the string
expansion faster. Switching to the static method would be a performance
hit. I agreed and I put the idea on the shelf.
Lately I've been thinking about it more and I did some research.
There are 247 protected instances of FlexibleStringExpander inside other
classes. Each of those containing classes might have hundreds of
instances. Many of the FlexibleStringExpander instances contain an empty
expression - they have nothing to expand.
To find out empirically how many FlexibleStringExpander instances are
being created, I created a little test. I modified the
FlexibleStringExpander constructor to count how many instances of each
expression were created. I set the cache properties to never expire and
then started OFBiz. I clicked on each main navigation tab and each sub
navigation tab. In other words, I just displayed the main page of each
component. Here are a few results (out of a list of hundreds):
Expression Count
-------------- ------
true 627
false 1679
screenlet 101
${description} 142
main-decorator 112
(empty expression) 16811
About half of the expressions tallied had only one instance. The test
results were repeatable - restarting OFBiz and following the same
actions produced the exact same results.
The results are enlightening. In the above list, only one of the
expressions needs expansion. 19330 of those FlexibleStringExpander
instances aren't needed.
Keep in mind that this was from displaying one page per component. In
actual use these numbers would be much higher.
So, getting back to my original static method idea...
What if we made the static method smarter? It first scans the expression
for "${" and if it isn't found (nothing to expand) it returns the
original string. If the expression needs expansion, it looks up the
expression in an "expression cache." If the expression isn't found in
the cache, the expression is pre-parsed and placed in the cache. The
pre-parsed expression is expanded and returned.
Now the only objects being created and saved in memory are cache entries
for expressions that require expansion. Using the results list above, we
would have one cache entry (${description}) instead of 19472
FlexibleStringExpander instances.
I'm not really pushing this idea - I'm just offering it up for comment.
We can't really know the net results unless a lot of re-coding is done.
Comments are welcome.
-Adrian