You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Kevin Riff <ke...@corel.com> on 2000/05/25 22:05:58 UTC

The introspecthelper(..) method is inefficient and unnecessary

Why does Tomcat's JSP engine generate code that relies on
JavaBeans-style introspection at runtime? I've just finished profiling a
web application which uses a custom tag library, and found that the
largest "hotspot" was the JspRuntimeLibrary.introspecthelper(..) method.
With my simple setup its consuming between 30% and 40% of the CPU time!!
I find this unacceptable. Why doesn't Tomcat perform the introspection
at translation-time and encode the actual method to call in the source
code that it generates? This could improve performance considerably.


Re: The introspecthelper(..) method is inefficient and unnecessary

Posted by Kevin Riff <ke...@corel.com>.
MANDAR RAJE wrote:

> We can have things like:
>
>  <jsp:useBean id="foo" class="bar" ..... />
>
>  for (....) {
>
>    int foo;
>    <jsp:setProperty name="foo" .../>
>
>  }
>
>
>  This means that for setP and getP, the bean object ("foo" in this
>  case) must be obtained from the pageContext at runtime. And this
>  means we will have access to the class of that bean "bar" and
>  thus the beanInfo only at runtime.
>
> Mandar.

Maybe you can't eliminate it entirely, but introspecting classes at runtime
should be avoided like the plague. I don't buy your argument that the bean's
class will only be available at runtime. Typically, the JSP page will be
translated into Java source code just in time to serve the first request.
Therefore, the bean's class must be available or the request will fail when
the compiled servlet is executed. It doesn't hurt anything to fail during the
translation step because a required class is missing if its going to fail at
runtime anyway. Even if you plan on pre-compiling the JSP page, it seems
reasonable to expect that all the supporting classes should be available to
the compiler. This is, after all, how compilers work.

When the JSP engine encounters a custom action tag, it generates code
something like this:

MyCustomTag _gobbledygook = new MyCustomTag();
_gobbledygook.setPageContext(pageContext);
_gobbledygook.setParent(null);
JspRuntimeLibrary.introspecthelper(_gobbledygook, "property", "value", null,
null, false);

Its obvious that _gobbledygook is definitely an instance of MyCustomTag. There
is no need to introspect it on every request. Its wasteful and time consuming
and it reflects badly on my web application. The last line should be replaced
with a direct method call to the property's setter method. This needs to be
determined only once at translation time.

_gobbledygook.setProperty("value");

In the example you sited, the class of the bean is clearly specified by the
"class" attribute (or in some cases the "type" attribute). This is all that's
required at translation time, there is no need to know the actual value the
bean will have. I suppose its possible to have a "setProperty" tag for a
property that doesn't exist in the declared class of the bean. In this case
introspecting at runtime is the only solution. However I feel this situation
will be rare and introspection should be used only as a fall-back position. In
the majority of cases, a "setProperty" tag may safely be translated into a
direct method call.

Let me elaborate on what I found out when I traced through the
introspecthelper(..) method. The following line seems innocuous but its
actually the source of the problem:

BeanInfo info = Introspector.getBeanInfo(bean.getClass());

The Introspector class maintains a cache so that it doesn't have to re-inspect
the same class over and over. The problem is that each time you invoke
getBeanInfo(..), it makes a complete copy of the BeanInfo in the cache. That
includes copies of all the Property/Event/MethodDescriptors. Under what I
would call a moderate load, I witnessed hundreds of thousands of these objects
being created in under a minute. Whoever wrote the Introspector code made an
extremely poor design choice, and I've already filed a bug report with Sun on
this issue. But Tomcat can't wait for Sun to fix the problem in the next major
release.

If the introspecthelper(..) method cannot be removed entirely, then it needs
to be overhauled. I recommend creating a separate cache where Tomcat can store
the information it needs. Since Tomcat is really only interested in finding
out the setter method for a given property, I suggest using a custom
data-structure built from hashtables rather than storing the BeanInfo
directly. This would eliminate the linear search which follows the call to
getBeanInfo(..), which is another time-waster.


Re: The introspecthelper(..) method is inefficient and unnecessary

Posted by MANDAR RAJE <ma...@pathfinder.eng.sun.com>.
Kevin Riff wrote:
> 
> Why does Tomcat's JSP engine generate code that relies on
> JavaBeans-style introspection at runtime? I've just finished profiling a
> web application which uses a custom tag library, and found that the
> largest "hotspot" was the JspRuntimeLibrary.introspecthelper(..) method.
> With my simple setup its consuming between 30% and 40% of the CPU time!!
> I find this unacceptable. Why doesn't Tomcat perform the introspection
> at translation-time and encode the actual method to call in the source
> code that it generates? This could improve performance considerably.

We can have things like:

 <jsp:useBean id="foo" class="bar" ..... />
 
 for (....) {
   
   int foo;
   <jsp:setProperty name="foo" .../>

 }

 
 This means that for setP and getP, the bean object ("foo" in this
 case) must be obtained from the pageContext at runtime. And this
 means we will have access to the class of that bean "bar" and
 thus the beanInfo only at runtime. 


Mandar.