Flow control by Exception

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Flow control by Exception

Bruce Ritchie-2
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
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Reply | Threaded
Open this post in threaded view
|

Re: Flow control by Exception

revusky
On Thu, Feb 5, 2009 at 10:37 PM, Bruce Ritchie <[hidden email]> wrote:

> 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.

Well, the eval and interpret built-ins are, I think, pretty clearly
advertised as being on the costly side performance-wise... It reparses
the string (i.e. mini-template) each time it is rendered -- as opposed
to regular template processing, where the template is already
pre-parsed into an AST when you render.

>
> 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();

The LookaheadSuccess thingy is something that any parser generated
using JavaCC does.

The current situation is that the parser in FM 2.3 is generated using
JavaCC but FM 2.4 uses FreeCC ( see http://freecc.googlecode.com )
that is a fork of JavaCC (my fork... long story....). Anyway, FreeCC
is where most of my open source hacking time is going now. I've been
systematically addressing a lot of the warts in JavaCC. This one not
yet.... I was aware of it, but other things had higher priority. OTOH,
the squeaky wheel gets the grease, so you can suppose that I'll be
having a look at this fairly soon.

>
> 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.

Yes, that is probably quite easy to address and I'll have a look at
that in FreeCC. But note that any improvements on this will only be
for 2.4.x. It may be a while before you can (at least while applying
proper caution) standardize on FM 2.4. The best you can do meanwhile,
I guess, is to see if you can lessen your use of ?eval.

>
> Is the 2.4 FMParser going to be better about this?

I think yes. Most probably... :-)

> 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). ?

Hmm... I dunno. Probably not... :-(

Now, for all I know, maybe Attila is going to jump up and say that he
is going to do something. He is more inclined to put energy into 2.3.
Just speaking for me, what energy I devote to hacking freemarker is
going to go into getting the 2.4 branch into shape for a stable
release. I just tend to think that whatever warts are in 2.3 (and
there are plenty...) are basically there. And actually, aside from
this issue, 2.4 really does address a lot of the shortcomings in 2.3.
(Annoying issues wrt java nulls, cleaning up scopes and variable
declaration, are just a couple of examples...) Most of that stuff has
has been done for like a couple of years, but we really just need to
get it stabilized and out there. Not a great project management
story.... it's mostly my fault I know... :-(

Regards,

Jonathan


>
>
> 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
> _______________________________________________
> FreeMarker-user mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/freemarker-user
>

------------------------------------------------------------------------------
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
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Reply | Threaded
Open this post in threaded view
|

Re: Flow control by Exception

Bruce Ritchie-2
Jonathan,

>> 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.
>
> Yes, that is probably quite easy to address and I'll have a look at
> that in FreeCC. But note that any improvements on this will only be
> for 2.4.x. It may be a while before you can (at least while applying
> proper caution) standardize on FM 2.4. The best you can do meanwhile,
> I guess, is to see if you can lessen your use of ?eval.
>

Yep, I switched to an eval(expressionString) put into the context
which caches the parsed templates resulting in a noticeable
improvement in performance.

>>
>> Is the 2.4 FMParser going to be better about this?
>
> I think yes. Most probably... :-)

Understood. fwiw filIInStackTrace is #2 in tick count (behind gc) at
anywhere between 5 and 10% of cpu time on the azul box I've been
testing on. Now not all of those exceptions are freemarker but a good
majority are (well were, I keep finding more things to cache).

>  And actually, aside from
> this issue, 2.4 really does address a lot of the shortcomings in 2.3.
> (Annoying issues wrt java nulls, cleaning up scopes and variable
> declaration, are just a couple of examples...) Most of that stuff has
> has been done for like a couple of years, but we really just need to
> get it stabilized and out there. Not a great project management
> story.... it's mostly my fault I know... :-(

I'm fine with things like this only going into 2.4 ... as long as I
know they are being looked at :)  We've actually toyed around with the
idea of rewriting the FreeMarker parser in the past to fix this issue
among others .. that is, until you started to work on FreeCC. Thanks
for looking into this!


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
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Reply | Threaded
Open this post in threaded view
|

Re: Flow control by Exception

Daniel Dekany
In reply to this post by revusky
Friday, February 6, 2009, 12:23:37 AM, Jonathan Revusky wrote:
[snip]
> Yes, that is probably quite easy to address and I'll have a look at
> that in FreeCC. But note that any improvements on this will only be
> for 2.4.x.
[snip]

Is that sure? When FreeCC will be stable/settled enough to be used for
2.4-final, then can't we also use it for 2.3.x?

--
Best regards,
 Daniel Dekany


------------------------------------------------------------------------------
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
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Reply | Threaded
Open this post in threaded view
|

Re: Flow control by Exception

Attila Szegedi-3
We would be able to use it for 2.3 as well, except for the fact that  
Jonathan is moving toward generating parsers that need Java 5 at  
runtime (uses generics etcetera). Which, honestly, is quite a  
defendable decision in 2009 :-)

Attila.

On 2009.02.06., at 11:55, Daniel Dekany wrote:

> Friday, February 6, 2009, 12:23:37 AM, Jonathan Revusky wrote:
> [snip]
>> Yes, that is probably quite easy to address and I'll have a look at
>> that in FreeCC. But note that any improvements on this will only be
>> for 2.4.x.
> [snip]
>
> Is that sure? When FreeCC will be stable/settled enough to be used for
> 2.4-final, then can't we also use it for 2.3.x?
>
> --
> Best regards,
> Daniel Dekany

------------------------------------------------------------------------------
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
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Reply | Threaded
Open this post in threaded view
|

Re: Flow control by Exception

Daniel Dekany
Friday, February 6, 2009, 12:59:49 PM, Attila Szegedi wrote:
> We would be able to use it for 2.3 as well, except for the fact that  
> Jonathan is moving toward generating parsers that need Java 5 at  
> runtime (uses generics etcetera). Which, honestly, is quite a  
> defendable decision in 2009 :-)

Ah, now I remember... And too bad.

As software dependency handling today is a quite immature field, I
guess it will be a long time while the world migrates from 2.3 to 2.4.
Because, in most infrastructures either all components of the system
use 2.3.x, or all of them use 2.4.x; you can't use both at once. To
solve this, there is the possibility of renaming the project package
to org.freemarker (that would be the correct package name anyway), but
that's very painful too for obvious reasons, means the adoption of 2.4
will be slow again. But that's at least something that technically can
be handled correctly; a component either clearly depends on 2.3, or on
2.4, and they can co-exist. Of course, someone will quickly point out
that this second (correct) solution will result in the slowest
adoption...

> Attila.
>
> On 2009.02.06., at 11:55, Daniel Dekany wrote:
>
>> Friday, February 6, 2009, 12:23:37 AM, Jonathan Revusky wrote:
>> [snip]
>>> Yes, that is probably quite easy to address and I'll have a look at
>>> that in FreeCC. But note that any improvements on this will only be
>>> for 2.4.x.
>> [snip]
>>
>> Is that sure? When FreeCC will be stable/settled enough to be used for
>> 2.4-final, then can't we also use it for 2.3.x?
>>
>> --
>> Best regards,
>> Daniel Dekany

--
Best regards,
 Daniel Dekany


------------------------------------------------------------------------------
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
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Reply | Threaded
Open this post in threaded view
|

Re: Flow control by Exception

revusky
In reply to this post by Bruce Ritchie-2
On Fri, Feb 6, 2009 at 12:52 AM, Bruce Ritchie <[hidden email]> wrote:
> Jonathan,
>
>>> 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.

Yes, it seems that this instance of LookaheadSuccess could perfectly
well be static. Actually, now that I actually look at this, it seems
quite easy to address. I just tweaked the 2.3 build.xml to make that
variable static. It's just a replace string on the generated
FMParser.java "private final LookaheadSuccess" -> "private static
final LookaheadSuccess".

And, yeah, AFAICS, there is no problem with just reusing the singleton
LookaheadSuccess object. It's really just a dummy object. So
basically:

svn co https://freemarker.svn.sourceforge.net/branches/2.3/freemarker
cd freemarker
ant

should build you a 2.3 freemarker.jar where that object is static.

I also have addressed this in FreeCC. It uses a static variable in that spot.

Thanks for bringing this up.

Regards,

JR

>>
>> Yes, that is probably quite easy to address and I'll have a look at
>> that in FreeCC. But note that any improvements on this will only be
>> for 2.4.x. It may be a while before you can (at least while applying
>> proper caution) standardize on FM 2.4. The best you can do meanwhile,
>> I guess, is to see if you can lessen your use of ?eval.
>>
>
> Yep, I switched to an eval(expressionString) put into the context
> which caches the parsed templates resulting in a noticeable
> improvement in performance.
>
>>>
>>> Is the 2.4 FMParser going to be better about this?
>>
>> I think yes. Most probably... :-)
>
> Understood. fwiw filIInStackTrace is #2 in tick count (behind gc) at
> anywhere between 5 and 10% of cpu time on the azul box I've been
> testing on. Now not all of those exceptions are freemarker but a good
> majority are (well were, I keep finding more things to cache).
>
>>  And actually, aside from
>> this issue, 2.4 really does address a lot of the shortcomings in 2.3.
>> (Annoying issues wrt java nulls, cleaning up scopes and variable
>> declaration, are just a couple of examples...) Most of that stuff has
>> has been done for like a couple of years, but we really just need to
>> get it stabilized and out there. Not a great project management
>> story.... it's mostly my fault I know... :-(
>
> I'm fine with things like this only going into 2.4 ... as long as I
> know they are being looked at :)  We've actually toyed around with the
> idea of rewriting the FreeMarker parser in the past to fix this issue
> among others .. that is, until you started to work on FreeCC. Thanks
> for looking into this!
>
>
> 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
> _______________________________________________
> FreeMarker-user mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/freemarker-user
>

------------------------------------------------------------------------------
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
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user