Did you try running the thing under a profiler? I tend to use
JProfiler here and I'm quite happy with it. 

        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.

> -----Original Message-----
> From: Shannon, Andrew [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, February 14, 2006 9:40 PM
> To: Tapestry users
> Subject: RE: Optimization Questions
> 
> Hey Geoff,
> 
> Thanks for the time put into your response.  I'm glad to hear that my
> fears on page/component loading are hopefully not necessary. We've been
> profiling with Mercury which is great.  Our bottleneck definitely
> appears to be the web tier, so I agree we have more to learn on how to
> leverage Tapestry better.  The interesting thing is our apps run great
> up to around a few hundred concurrent users.  But as I mentioned it
> crawls at the thousand plus mark.  Preliminary results showed us a
> component or two to optimize, but we're also seeing serious latency in
> the ApplicationServlet.  I'll be interested to see what the data really
> means and what it can point to in our apps.  Thanks again.
> 
> - Andrew
> 
<snip>




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

Reply via email to