Don't forget about the Tapestry-Prop library at http://howardlewisship.com/tapestry-javaforge/tapestry-prop/ Combined with the "dot-pruning" technique this will let you eliminate a lot of OGNL.

-Ryan

Vincent wrote:
Hi ,

That may explain a lot why the performance of the my application slow
down a lot recently.
But anyway , is there any plan to improve the performance of OGNL ,
since Tapestry 4.0 already released?

On 3/26/06, Adam Zimowski <[EMAIL PROTECTED]> wrote:
Hi Andreas,

FYI, OGNL is one of the biggest bottlencecks in Tapestry. I'm learning
about it from performance testing my own app, but I could not say it
better than what Patrick explained a while back on this list. His post
was regarding Tap 3.0.3, but from my Tap4 tests, the OGNL performance
is still very much a case for performance tweaks. In short, try to
limit your OGNL usage to what's absolutely necessary, and do the rest
in plain Java. My app is growing large very quickly, but I'm able to
keep OGNL down to simple one-dot expressions.

Perhaps you've seen Patrick's post (it's really well explained), but
I'm including it here:
-------------------------------------------------------------------------

From: Patrick Casey <[EMAIL PROTECTED]>     Mailed-By: jakarta.apache.org
Reply-To: Tapestry users <tapestry-user@jakarta.apache.org>
To: Tapestry users <tapestry-user@jakarta.apache.org>
Date: Feb 15, 2006 11:38 AM
Subject: RE: Optimization Questions

The last time I did a serious performance attach on a Tapestry 3.0.3
app, by far the biggest performance bottleneck was the demon OGNL. Howard
and I went round and round on that one, but the upshot is that Howard's
using OGNL right, and OGNL is actually a decent reflection package (and
hence faster than, say, Apache PropUtils), but it's still not native code.

       Given that some page renders can require literally thousands of OGNL
calls (I was up at like 1800 distinct evaluations for one page), its often
the bottleneck.

       I've pasted my OGNL performance hints below. None of it's rocket
science, but aggressively following these techniques knocked about 50% off
the page render time on my forms, so there's some serious performance to be
gained.

       --- Pat

   Rules to Make OGNL Run Faster:


**Dot Pruning:

Reduce the number of "dots" in your calls. For example, lets say you had a
call that read: "ognl:foo.bar.dog". That's a three-hopper as far as OGNL is
concerned, requiring three times the work of a one hopper like "ognl:dog".
You can make the thing run 3X as fast if your go into your page class and
create a getter and setter for "dog" e.g.



Public String getDog() {

           Foo foo = getFoo();

           If (foo == null)

                       Return null;

           Bar bar = getBar();

           If (bar == null)

                       Return null;

           Return bar.getDog();

}



Public void setDog(String value) {

           Foo foo = getFoo();

           If (foo == null)

                       Return;

           Bar bar = getBar();

           If (bar == null)

                       Return;

           Bar.setDog(value);

}



           What we've done is created two java stub classes that do 2/3 of
the work for OGNL so it only has to make one "hop" to get at the methods it
needs. Net result is it'll run 3X as fast.


**Be Static:


           OGNL isn't smart enough to realize that a reference to a public
static final object is, in fact, static. It resolves the whole thing via
inspection each time. So if you want to make an expression that reads, for
example:



<span jwcid="@Insert" value="ognl:@[EMAIL PROTECTED]" />


           It's faster to do:


           <span jwcid="@Insert" value="Monday" />


           You're kind of Sol if you change "Monday" to "Mon" mind you, so
I wouldn't switch over to literals like this until rollout time, but it does
make a difference.


**Avoid Putting Components Inside Foreach:

There's a lot of OGNL grinding going on behind the scenes to support a
foreach, and even more ognl grinding going on to call a component. So if you
put the one inside the other, well, CPU cycles burn. So in many cases:



<span jwcid="@Foreach" source="ognl:listOfDogs" values="ognl:currentDog">
       <span jwcid="@DogDisplay" dog="ognl:currentDog"/>
 <span>


Is *dramatically* slower than moving the foreach down into the DogDisplay
component e.g.

<span jwcid="@ListOfDogsDisplay" listOfDogs="ognl:listOfDogs" />


And then combing the foreach and the dogdisplay logic inside of one
component. Otherwise every time the sub component gets called there's at
least one ognl set/get pair being executed to push data into the component
and pluck it out again. Basically pretend you're working in a system which
has *really* inefficient method call overhead and view components as
methods. Then optimize to reduce method calls.

**Notes:

If you do your own profiling, one warning I do want to give is that on
JProfiler at least, it can "hide" the true culprit in the bowels of the call
stack. So if you have an ognl expression that reads
"ognl:foo.bar.thisMethodTakesForever", it'll show up as a lot of CPU time
belonging to ognlGet until you dive into the call stack and get to
whatever's at the pointy end of the get. Most of the time the actual get is
trivial so all the time really is going into OGNL, but sometimes if you have
expensive gets (or sets) it can make OGNL look worse than it is.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to