blue-sky
blue-sky

Reputation: 53846

Which is faster, JSTL or Java?

There is some JSTL logic which I refactored into Java. I didn't consider performance at the time but just assumed that Java would be faster. Is this assumption correct?

the JSTL code contained for each statements which were refactored into Java for loops. I'm basing my assumption that the JSTL code must be first converted to Java before compilation.

Upvotes: 3

Views: 3403

Answers (5)

Amir Pashazadeh
Amir Pashazadeh

Reputation: 7312

There will be some overhead, because for is a language construct, and <c:foreach> will not be compiled to a just a for loop. A JSTL tag is just like other tags, they are executed by container, and container will invoke their life-cycle and callback methods. If you look at the generated source code of a JSP in a container (such as Tomcat, or WebLogic), you can see that using a simple tag has lots of overhead.

But I believe this overhead is not comparable to your data-access, network, and ... delays. So ignore this little delay, and use JSTL and tags to make your JSP more readable and maintainable.

Updated:

By the way when you use JSTL (or other tag libraries) you usually use JSP EL too, and evaluation of EL has a little overhead. But again these overheads do not count compared to data-access, network latency and ....

Upvotes: 0

Asaph
Asaph

Reputation: 162821

You assumption was (mostly) incorrect. Your servlet container (eg. Tomcat) will compile all jsp pages into java servlets, and then to java bytecode, which is ultimately what gets run when jsp pages are requested. So jsp pages get transparently translated to java code anyway. There may be a performance difference between the jstl custom tag lib implementation logic and your java code, but this would be due to specific implementation, not java vs. jstl.

Under the default configuration for Tomcat, the jsp compilation doesn't take place until the first time the jsp resource is accessed, so there is a startup penalty for the very first request (only) of a jsp page. If you're concerned about that first time hit, you can configure jsp pages to get pre-compiled. Not worth the trouble for most use cases.

Upvotes: 2

Javier
Javier

Reputation: 12398

Not only the JSTL code has to be converted to java source code and then compiled (which wouldn't affect runtime performance) but also there is a small overhead because of the creation of Tag instances and access to the request attributes (which are local variables in a plain Java loop). I think that most of this cost could be hidden by compiler optimizations, such as escape analysis, and/or would be enough small in comparison with other "costs" such as network latency, but it would have it toll anyway.

Out of curiosity, I looked at a JSP compiled by Tomcat 6. This is the source code generated from a simple c:forEach tag...

  private boolean _jspx_meth_c_005fforEach_005f0(PageContext _jspx_page_context)
          throws Throwable {
    PageContext pageContext = _jspx_page_context;
    JspWriter out = _jspx_page_context.getOut();
    //  c:forEach
    org.apache.taglibs.standard.tag.el.core.ForEachTag _jspx_th_c_005fforEach_005f0 = (org.apache.taglibs.standard.tag.el.core.ForEachTag) _005fjspx_005ftagPool_005fc_005fforEach_0026_005fvar_005fitems.get(org.apache.taglibs.standard.tag.el.core.ForEachTag.class);
    _jspx_th_c_005fforEach_005f0.setPageContext(_jspx_page_context);
    _jspx_th_c_005fforEach_005f0.setParent(null);
    _jspx_th_c_005fforEach_005f0.setVar("session");
    _jspx_th_c_005fforEach_005f0.setItems("${session_info}");
    int[] _jspx_push_body_count_c_005fforEach_005f0 = new int[] { 0 };
    try {
      int _jspx_eval_c_005fforEach_005f0 = _jspx_th_c_005fforEach_005f0.doStartTag();
      if (_jspx_eval_c_005fforEach_005f0 != javax.servlet.jsp.tagext.Tag.SKIP_BODY) {
        do {
          out.write(" \r\n");
          out.write(" <TR>\r\n");
          out.write("     <TD>"); //etc...
          if (_jspx_meth_c_005fout_005f0(_jspx_th_c_005fforEach_005f0, _jspx_page_context, _jspx_push_body_count_c_005fforEach_005f0))
            return true;
          out.write("\r\n");
          out.write("     <TD>");
          if (_jspx_meth_c_005fif_005f0(_jspx_th_c_005fforEach_005f0, _jspx_page_context, _jspx_push_body_count_c_005fforEach_005f0))
            return true;
          int evalDoAfterBody = _jspx_th_c_005fforEach_005f0.doAfterBody();
          if (evalDoAfterBody != javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN)
            break;
        } while (true);
      }
      if (_jspx_th_c_005fforEach_005f0.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE) {
        return true;
      }
    } catch (Throwable _jspx_exception) {
      while (_jspx_push_body_count_c_005fforEach_005f0[0]-- > 0)
        out = _jspx_page_context.popBody();
      _jspx_th_c_005fforEach_005f0.doCatch(_jspx_exception);
    } finally {
      _jspx_th_c_005fforEach_005f0.doFinally();
      _005fjspx_005ftagPool_005fc_005fforEach_0026_005fvar_005fitems.reuse(_jspx_th_c_005fforEach_005f0);
    }
    return false;
  }

Upvotes: 1

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85779

Java scriptlets will be faster than JSTL code since it's pure Java code and doesn't need any parsing when the JSP gets converted into a Servlet class. Still, you should avoid the usage of scriptlets as explained here.

If you use Facelets instead of JSP as your technology for presentation layer, there's no need to use scriptlets at all.

IMHO, I doubt that 100 or 200 ms overhead to parse the JSTL (and other tags) would be of great impact for your application.

Upvotes: 0

austin
austin

Reputation: 5876

I think JSTL should be compiled into Java bytecode, so I would expect them to be the same. You could probably expect better performance if you wrote the code directly in Java, but the compiler probably is better at doing optimization than you think.

If you're really concerned, I would run a profiler and compare the results.

Upvotes: 1

Related Questions