Flow control by Exception

Bruce Ritchie <[email protected]>
Newsgroups gmane.comp.web.freemarker.user
Message-ID <[email protected]>
Hi,

I've been hunting down some performance issues in our application and
one of the things I noticed is that the FMParser/FMParserTokenManager
seems to do flow control by exception. In general that is never a good
idea but it can really impact performance in our application because
of our heavy reliance on FreeMarker for our display layer.

To give an example, adding

${"1 + 2"?eval} to a template will guarantee that an IOException will
be created and thrown, caught and handled. I've annotated the
FMParserTokenManager to spit out any time an IOException is thrown and
here is a portion of the stack trace from adding the above call:

java.io.IOException
	at freemarker.core.SimpleCharStream.FillBuff(SimpleCharStream.java:111)
	at freemarker.core.SimpleCharStream.readChar(SimpleCharStream.java:188)
	at freemarker.core.SimpleCharStream.BeginToken(SimpleCharStream.java:129)
	at freemarker.core.FMParserTokenManager.getNextToken(FMParserTokenManager.java:6430)
	at freemarker.core.FMParser.jj_scan_token(FMParser.java:4577)
	at freemarker.core.FMParser.jj_3_1(FMParser.java:3658)
	at freemarker.core.FMParser.jj_2_1(FMParser.java:2967)
	at freemarker.core.FMParser.PrimaryExpression(FMParser.java:268)
	at freemarker.core.FMParser.UnaryExpression(FMParser.java:319)
	at freemarker.core.FMParser.MultiplicativeExpression(FMParser.java:435)
	at freemarker.core.FMParser.AdditiveExpression(FMParser.java:385)
	at freemarker.core.FMParser.RangeExpression(FMParser.java:556)
	at freemarker.core.FMParser.RelationalExpression(FMParser.java:511)
	at freemarker.core.FMParser.EqualityExpression(FMParser.java:476)
	at freemarker.core.FMParser.AndExpression(FMParser.java:585)
	at freemarker.core.FMParser.OrExpression(FMParser.java:608)
	at freemarker.core.FMParser.Expression(FMParser.java:221)
	at freemarker.core.StringBuiltins$evalBI.calculateResult(StringBuiltins.java:169)
	at freemarker.core.StringBuiltins$StringBuiltIn._getAsTemplateModel(StringBuiltins.java:71)


Note that this isn't isolate to ?eval - I swear an IOException or two
is thrown anytime a template is loaded, though not always from the
same place.

I've also noticed that FMParser uses an exception LookaheadSuccess  to
do exactly what the name implies. There is even a variable assigned to
it, unfortunately it's not static

final private LookaheadSuccess jj_ls = new LookaheadSuccess();

If it was static it at the very least wouldn't incur the
fillInStackTrace JVM call which is so painful performance wise - being
static isn't an issue in this case since this exception is never
rethrown as best as I can tell.

Is the 2.4 FMParser going to be better about this? Can anything be
done for 2.3.x to help stop this performance impacting pattern (beyond
the hacks I've made to fix/workaround these issues). ?


Regards,

Bruce Ritchie

------------------------------------------------------------------------------
Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM)
software. With Adobe AIR, Ajax developers can use existing skills and code to
build responsive, highly engaging applications that combine the power of local
resources and data with the reach of the web. Download the Adobe AIR SDK and
Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.