You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Patrick Casey <pa...@adelphia.net> on 2005/11/20 06:20:18 UTC
Ways to Make OGNL Run Faster
Since this is my day to profile (it gives me something to do
while my wife watched college football), I spent most of today working (with
the aid of JProfiler) on seeing where the time in my Tapestry apps was
going. Not surprisingly if you read my last post, a disproportionate amount
of it ends up in OGNL (and when I say disproportionate, I mean over half of
total clock cycles on some particularly complex forms). Given that we're
probably stuck with OGNL for the foreseeable future, I decided to see what,
if anything, I could do to speed it up and I thought I'd share the results.
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:@constants.DaysOfWeek@Monday"
/>
It's *much*, *much* 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 big 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.
RE: Ways to Make OGNL Run Faster
Posted by Patrick Casey <pa...@adelphia.net>.
Based on the 3.0.3 code that'd probably be doable (and I think 4.0
is quite a bit more pluggable (and flexible) with its data binders than
3.0.3. Practically speaking, the number of hops doesn't matter much from a
complexity standpoint, so if you have the code to automatically swap
"ognl:foo" into a prop call, then
"ognl:foo.bar" is really just the same thing, only twice.
The places it would get more complicated are expressions that use
operators e.g.
"ognl:foo > bar"
Or
"ognl:new Object[] {foo, bar}"
Calls like that will probably have to remain OGNL for the
foreseeable futures (because I doubt Howard wants to write an expression
parser and compiler), but, as Howard has mentioned, the 80% case is just
simple gets and sets, so even if he can only speed up that limited subset of
the expressions out there, it'd have a disproportionate (and positive)
impact on performance.
--- Pat
> -----Original Message-----
> From: news [mailto:news@sea.gmane.org] On Behalf Of Marcus Brito
> Sent: Tuesday, November 22, 2005 4:07 AM
> To: tapestry-user@jakarta.apache.org
> Subject: Re: Ways to Make OGNL Run Faster
>
> Howard Lewis Ship <hlship <at> gmail.com> writes:
>
> > I'm squandering some cycles on tapestry-prop, which adds a "prop:"
> > prefix. It makes the cost of a single "hop" drop by a factor of 10 or
> > so.
>
> Tt would be nice to add a piece of code to automatically use "prop" if the
> OGNL
> expression is just one hop away; this would give a nice speed boost to
> existing
> applications, without changing a single line.
>
> Maybe the whole "ognl:" thing is wrong and it should have been called
> "ref:" or
> something like that, and the reference resolver should have been
> pluggable. This
> would be a very nice improvement for Tapestry 4.x -- the "ognl:" prefix
> could be
> kept for a couple years for backwards compatibility.
>
> -- Marcus Brito <mb...@gmail.com>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
Re: Ways to Make OGNL Run Faster
Posted by Marcus Brito <mb...@gmail.com>.
Howard Lewis Ship <hlship <at> gmail.com> writes:
> I'm squandering some cycles on tapestry-prop, which adds a "prop:"
> prefix. It makes the cost of a single "hop" drop by a factor of 10 or
> so.
Tt would be nice to add a piece of code to automatically use "prop" if the OGNL
expression is just one hop away; this would give a nice speed boost to existing
applications, without changing a single line.
Maybe the whole "ognl:" thing is wrong and it should have been called "ref:" or
something like that, and the reference resolver should have been pluggable. This
would be a very nice improvement for Tapestry 4.x -- the "ognl:" prefix could be
kept for a couple years for backwards compatibility.
-- Marcus Brito <mb...@gmail.com>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
Re: Ways to Make OGNL Run Faster
Posted by Howard Lewis Ship <hl...@gmail.com>.
I've put up the home page, as http://howardlewisship.com/tapestry-prop/
I don't have a download for this yet; eventually, it will be
distributed via maven. For the moment, it requires a quick download of
the source via SVN and build via Maven2.
I expect to add support for complex properties ("foo.bar.baz") before
a final 1.0 release.
On 11/20/05, Howard Lewis Ship <hl...@gmail.com> wrote:
> I'm squandering some cycles on tapestry-prop, which adds a "prop:"
> prefix. It makes the cost of a single "hop" drop by a factor of 10 or
> so.
>
> I hope to expand it to support simple property paths, i.e.,
> "foo.bar.baz" would expand, automatically, to
> "getFoo().getBar().getBaz()" (or setBaz(), as appropriate). That does
> open up new questions about handling nulls, as well as special cases,
> such as java.util.Map.
>
> I'm looking for some kind of 80/20, where most of the time, you can
> use prop:, and swich to ognl: only when you need a little more
> expressive power.
>
> The joy of Tapestry 4.0 is that these changes don't need to wait for
> 4.1, or delay 4.0. Just include the tapestry-prop library on the
> classpath and the configuration meshes together, care of HiveMind.
>
>
>
> On 11/20/05, Patrick Casey <pa...@adelphia.net> wrote:
> > I should also point out that (still more) slogging through the bowels of
> > tapestry databinders and OGNL has convinced me that the combination isn't
> > quite as clueless about static as I imagined. A truly static binding is
> > still faster than an "ognl:@package.Class@property" binding, but a static
> > ognl binding is quite a bit faster than a dynamic one as Howard (and OGNL)
> > try to only resolve it once.
> >
> > So performance goes:
> >
> > "Monday" >> "ognl:@constants.DaysOfWeek@Monday" >> "ognl:getToday()"
> >
> > --- Pat
> >
> > > -----Original Message-----
> > > From: Leonardo Quijano Vincenzi [mailto:leonardo@dtqsoftware.com]
> > > Sent: Saturday, November 19, 2005 11:52 PM
> > > To: Tapestry users
> > > Subject: Re: Ways to Make OGNL Run Faster
> > >
> > > Now for the obvious question... what plans are there to make this
> > > transparently faster? I mean, if the framework lets you put
> > > "foo.bar.x.y.z.help" in an ognl expression, it must take every step
> > > possible to make that as fast as a single "getHelp()" instruction. I
> > > mean, if Hibernate can do it, why OGNL can't?
> > >
> > > Maybe Tapestry can learn from other frameworks. Though I'm specially
> > > worried about start-up and compilation time on devel mode, more than
> > > runtime performance (but maybe that's because I'm not requiring my
> > > web-apps to handle millions of users, not right now).
> > >
> > > --
> > > Ing. Leonardo Quijano Vincenzi
> > > Director Técnico
> > > DTQ Software
> >
> >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
> >
> >
>
>
> --
> Howard M. Lewis Ship
> Independent J2EE / Open-Source Java Consultant
> Creator, Jakarta Tapestry
> Creator, Jakarta HiveMind
>
> Professional Tapestry training, mentoring, support
> and project work. http://howardlewisship.com
>
--
Howard M. Lewis Ship
Independent J2EE / Open-Source Java Consultant
Creator, Jakarta Tapestry
Creator, Jakarta HiveMind
Professional Tapestry training, mentoring, support
and project work. http://howardlewisship.com
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
Re: Ways to Make OGNL Run Faster
Posted by Howard Lewis Ship <hl...@gmail.com>.
I'm squandering some cycles on tapestry-prop, which adds a "prop:"
prefix. It makes the cost of a single "hop" drop by a factor of 10 or
so.
I hope to expand it to support simple property paths, i.e.,
"foo.bar.baz" would expand, automatically, to
"getFoo().getBar().getBaz()" (or setBaz(), as appropriate). That does
open up new questions about handling nulls, as well as special cases,
such as java.util.Map.
I'm looking for some kind of 80/20, where most of the time, you can
use prop:, and swich to ognl: only when you need a little more
expressive power.
The joy of Tapestry 4.0 is that these changes don't need to wait for
4.1, or delay 4.0. Just include the tapestry-prop library on the
classpath and the configuration meshes together, care of HiveMind.
On 11/20/05, Patrick Casey <pa...@adelphia.net> wrote:
> I should also point out that (still more) slogging through the bowels of
> tapestry databinders and OGNL has convinced me that the combination isn't
> quite as clueless about static as I imagined. A truly static binding is
> still faster than an "ognl:@package.Class@property" binding, but a static
> ognl binding is quite a bit faster than a dynamic one as Howard (and OGNL)
> try to only resolve it once.
>
> So performance goes:
>
> "Monday" >> "ognl:@constants.DaysOfWeek@Monday" >> "ognl:getToday()"
>
> --- Pat
>
> > -----Original Message-----
> > From: Leonardo Quijano Vincenzi [mailto:leonardo@dtqsoftware.com]
> > Sent: Saturday, November 19, 2005 11:52 PM
> > To: Tapestry users
> > Subject: Re: Ways to Make OGNL Run Faster
> >
> > Now for the obvious question... what plans are there to make this
> > transparently faster? I mean, if the framework lets you put
> > "foo.bar.x.y.z.help" in an ognl expression, it must take every step
> > possible to make that as fast as a single "getHelp()" instruction. I
> > mean, if Hibernate can do it, why OGNL can't?
> >
> > Maybe Tapestry can learn from other frameworks. Though I'm specially
> > worried about start-up and compilation time on devel mode, more than
> > runtime performance (but maybe that's because I'm not requiring my
> > web-apps to handle millions of users, not right now).
> >
> > --
> > Ing. Leonardo Quijano Vincenzi
> > Director Técnico
> > DTQ Software
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>
>
--
Howard M. Lewis Ship
Independent J2EE / Open-Source Java Consultant
Creator, Jakarta Tapestry
Creator, Jakarta HiveMind
Professional Tapestry training, mentoring, support
and project work. http://howardlewisship.com
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
RE: Ways to Make OGNL Run Faster
Posted by Patrick Casey <pa...@adelphia.net>.
I should also point out that (still more) slogging through the bowels of
tapestry databinders and OGNL has convinced me that the combination isn't
quite as clueless about static as I imagined. A truly static binding is
still faster than an "ognl:@package.Class@property" binding, but a static
ognl binding is quite a bit faster than a dynamic one as Howard (and OGNL)
try to only resolve it once.
So performance goes:
"Monday" >> "ognl:@constants.DaysOfWeek@Monday" >> "ognl:getToday()"
--- Pat
> -----Original Message-----
> From: Leonardo Quijano Vincenzi [mailto:leonardo@dtqsoftware.com]
> Sent: Saturday, November 19, 2005 11:52 PM
> To: Tapestry users
> Subject: Re: Ways to Make OGNL Run Faster
>
> Now for the obvious question... what plans are there to make this
> transparently faster? I mean, if the framework lets you put
> "foo.bar.x.y.z.help" in an ognl expression, it must take every step
> possible to make that as fast as a single "getHelp()" instruction. I
> mean, if Hibernate can do it, why OGNL can't?
>
> Maybe Tapestry can learn from other frameworks. Though I'm specially
> worried about start-up and compilation time on devel mode, more than
> runtime performance (but maybe that's because I'm not requiring my
> web-apps to handle millions of users, not right now).
>
> --
> Ing. Leonardo Quijano Vincenzi
> Director Técnico
> DTQ Software
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
RE: Ways to Make OGNL Run Faster
Posted by Patrick Casey <pa...@adelphia.net>.
I slogged through some of Howard's 3.0.3 code, and he already does a
wee bit of collapsing e.g. "ognl:page.foo" becomes just "ognl:foo" since the
page is the root of the context. He's just short circuiting a few of the
most obvious (and presumably common) cases though rather than implementing a
global collapse routine.
He's also recently mentioned that he's been looking at the same
issue I was (although he was more concerned with the speed of a single "hop"
rather than reducing the hop count). It sounds like any changes there will
be post 4.0 (maybe 4.1 ish).
I can't help but wonder though if switching to a different resolver
library might be faster. I'm seeing really whopping big times on OGNL
resolves, far larger than I'm seeing in other parts of my code where I'm
introspecting bean sets and gets via the BeanUtils package (which admittedly
is far less powerful than OGNL, but you'd hope the simple cases would
resolve to similar timings). Any change though would have to be incremental
to avoid breaking older stuff e.g. add a new binder in 4.1 and continue to
support OGNL as a legacy approach.
Along those lines, I suspect that a "beanUtil:" binder which
supported *only* gets and sets would be far faster and good enough for 80%
of the cases out there (since it doesn't require setting up an execution
context). I've also suggested that javascript might work, but I can't
guarantee it'd be any faster as my recollection is that Rhino context
generation and parse times are non-trivial (I distinctly recall writing a
parsed expression cache for something or other).
Anyway, for now, I've just decided to do what I can to make working
with OGNL faster.
<shrug>
--- Pat
> -----Original Message-----
> From: Leonardo Quijano Vincenzi [mailto:leonardo@dtqsoftware.com]
> Sent: Saturday, November 19, 2005 11:52 PM
> To: Tapestry users
> Subject: Re: Ways to Make OGNL Run Faster
>
> Now for the obvious question... what plans are there to make this
> transparently faster? I mean, if the framework lets you put
> "foo.bar.x.y.z.help" in an ognl expression, it must take every step
> possible to make that as fast as a single "getHelp()" instruction. I
> mean, if Hibernate can do it, why OGNL can't?
>
> Maybe Tapestry can learn from other frameworks. Though I'm specially
> worried about start-up and compilation time on devel mode, more than
> runtime performance (but maybe that's because I'm not requiring my
> web-apps to handle millions of users, not right now).
>
> --
> Ing. Leonardo Quijano Vincenzi
> Director Técnico
> DTQ Software
>
>
> Patrick Casey wrote:
> >
> >
> > Since this is my day to profile (it gives me something to do
> > while my wife watched college football), I spent most of today working
> (with
> > the aid of JProfiler) on seeing where the time in my Tapestry apps was
> > going. Not surprisingly if you read my last post, a disproportionate
> amount
> > of it ends up in OGNL (and when I say disproportionate, I mean over half
> of
> > total clock cycles on some particularly complex forms). Given that we're
> > probably stuck with OGNL for the foreseeable future, I decided to see
> what,
> > if anything, I could do to speed it up and I thought I'd share the
> results.
> >
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
Re: Ways to Make OGNL Run Faster
Posted by Leonardo Quijano Vincenzi <le...@dtqsoftware.com>.
Now for the obvious question... what plans are there to make this
transparently faster? I mean, if the framework lets you put
"foo.bar.x.y.z.help" in an ognl expression, it must take every step
possible to make that as fast as a single "getHelp()" instruction. I
mean, if Hibernate can do it, why OGNL can't?
Maybe Tapestry can learn from other frameworks. Though I'm specially
worried about start-up and compilation time on devel mode, more than
runtime performance (but maybe that's because I'm not requiring my
web-apps to handle millions of users, not right now).
--
Ing. Leonardo Quijano Vincenzi
Director Técnico
DTQ Software
Patrick Casey wrote:
>
>
> Since this is my day to profile (it gives me something to do
> while my wife watched college football), I spent most of today working (with
> the aid of JProfiler) on seeing where the time in my Tapestry apps was
> going. Not surprisingly if you read my last post, a disproportionate amount
> of it ends up in OGNL (and when I say disproportionate, I mean over half of
> total clock cycles on some particularly complex forms). Given that we're
> probably stuck with OGNL for the foreseeable future, I decided to see what,
> if anything, I could do to speed it up and I thought I'd share the results.
>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org