3

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.

austin
  • 5,816
  • 2
  • 32
  • 40
blue-sky
  • 51,962
  • 152
  • 427
  • 752
  • That's premature optimization: it'll make your code dirtier without any significant impact on performance. Tune your SQL queries, that's where time is lost in a typical application. – JB Nizet Feb 23 '13 at 23:26
  • @JB Nizet 'dirtier code' ? Should as much logic as possible not be in the jsp, and logic moved to service layer ? – blue-sky Feb 23 '13 at 23:43
  • 1
    JSPs shouldn't use scriptlets. The JSTL has been designed to avoid scriptlets, and be able to write code in a cleaner, simpler and safer way inside JSPs. Replacing the forEach tag with a for loop inside scriptlets is dirty. If you mean that you moved the HTML generation to a Java class, instead of writing it in JSPs, then it's even worse: you're back to servlets 1.0, when JSPs didn't exist and you had lots of HTML code inside Java code, making it unmaintainable. – JB Nizet Feb 23 '13 at 23:47
  • If you moved code which has nothing to do with HTML generation outside of the JSP, then that's a good thing. I wouldn't call that "JSTL code", though. And moving it ouyside of the JSP shouldn't be done for performance reasons, but for maintainability and good design reasons. – JB Nizet Feb 23 '13 at 23:50
  • @JB Nizet the jstl collection was being iterated and different values were outputted using jstl if statements. So instead of the jstl performing an if on the collection searching for the value, the collection is now tailored for that .jsp so no conditional code in the jstl. The backend java code is now performing the filtering instead of the jstl. – blue-sky Feb 23 '13 at 23:53
  • @JB Nizet just to be clear, there are no scriplets or html being generated from java. – blue-sky Feb 23 '13 at 23:58
  • 1
    That's cool. You have a clean model, providing useful encapsulated methods to make the view's job easier. Your code is now cleaner, which is the most important part. It's also probably more efficient, but the gain is probably insignificant, unless the collection is very large and you went from an O(n^2) code to O(n) code (which is unlikely given your description) – JB Nizet Feb 23 '13 at 23:58

5 Answers5

2

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.

Asaph
  • 159,146
  • 25
  • 197
  • 199
  • When I use tomcat at my work place, if I see a code error in the JSP, I just make a hot edit on the JSP deployed on the tomcat (modifying HTML/JSTL code), and I just refresh the browser to reflect the changes. Does this mean that there is a Tomcat configuration to recompile the JSP on every get request? Note that this doesn't happen on JBoss (that's built on top of Tomcat) – Luiggi Mendoza Feb 23 '13 at 23:09
  • Nope, Tomcat recompiles the JSP if it is changed from last compilation. – Amir Pashazadeh Feb 23 '13 at 23:15
1

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.

austin
  • 5,816
  • 2
  • 32
  • 40
1

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;
  }
Javier
  • 12,100
  • 5
  • 46
  • 57
  • yep, did that also and straight away checked if there was any performance difference between for and while loops, unfortunately there was'nt – blue-sky Feb 24 '13 at 00:05
0

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.

Community
  • 1
  • 1
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • but as Asaph mentioned in his/her answer. this is just a first time hit for the first request of the page ? Are you saying that using java code in servlet is faster than usinig jstl in jsp ? – blue-sky Feb 23 '13 at 23:03
  • @user470184 yes, that's what we both are saying. Still, that's not a reason to use scriptlets at all. See the link in my answer and [this link](http://balusc.blogspot.com/2009/09/webapplication-performance-tips-and.html#FlushTheBufferEarly) between the comments of the answer. – Luiggi Mendoza Feb 23 '13 at 23:06
0

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 ....

Amir Pashazadeh
  • 7,170
  • 3
  • 39
  • 69
  • I'm late to the party, but I just had this discussion. I don't believe that using JSTL makes your JSP more maintainable. If you're writing a java application you know pure java without thinking twice, most likely. JSTL has it's own syntax so someone not familiar with it would have to do some checking as opposed to being able to just read the regular Java code. – Encryption Dec 23 '16 at 16:42