3

JavaにリファクタリングしたJSTLロジックがいくつかあります。当時、パフォーマンスについては考慮していませんでしたが、Javaの方が高速であると想定していました。この仮定は正しいですか?

Javaforループにリファクタリングされた各ステートメントに含まれるJSTLコード。私は、JSTLコードをコンパイルする前に最初にJavaに変換する必要があるという私の仮定に基づいています。

4

5 に答える 5

2

あなたの仮定は(ほとんど)間違っていました。サーブレットコンテナ(Tomcatなど)は、すべてのjspページをJavaサーブレットにコンパイルし、次にjavaバイトコードにコンパイルします。これは最終的にjspページが要求されたときに実行されるものです。したがって、jspページはとにかくJavaコードに透過的に変換されます。jstlカスタムタグlib実装ロジックとJavaコードの間にパフォーマンスの違いがあるかもしれませんが、これはJavaとjstlではなく、特定の実装によるものです。

Tomcatのデフォルト構成では、jspリソースに最初にアクセスするまで、jspコンパイルは実行されないため、jspページの最初の要求(のみ)に対して起動時のペナルティが発生します。その最初のヒットが心配な場合は、プリコンパイルされるようにjspページを構成できます。ほとんどのユースケースで問題を起こす価値はありません。

于 2013-02-23T22:56:17.917 に答える
1

JSTLはJavaバイトコードにコンパイルする必要があると思うので、同じであると思います。Javaで直接コードを記述した場合は、おそらくパフォーマンスが向上することが期待できますが、コンパイラーは、おそらく、思ったよりも最適化を行うのに優れています。

本当に心配な場合は、プロファイラーを実行して結果を比較します。

于 2013-02-23T22:57:06.507 に答える
1

JSTLコードをJavaソースコードに変換してからコンパイルする必要があるだけでなく(ランタイムパフォーマンスには影響しません)、タグインスタンスの作成とリクエスト属性(ローカル変数)へのアクセスのためにわずかなオーバーヘッドがありますプレーンJavaループ内)。このコストの大部分は、エスケープ分析などのコンパイラの最適化によって隠されたり、ネットワーク遅延などの他の「コスト」と比較して十分に小さいと思いますが、とにかくコストがかかります。

好奇心から、Tomcat 6でコンパイルされたJSPを見ました。これは単純なc:forEachタグから生成されたソースコードです...

  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;
  }
于 2013-02-23T23:02:25.613 に答える
0

Javaスクリプトレットは純粋なJavaコードであり、JSPがサーブレットクラスに変換されるときに解析を必要としないため、JSTLコードよりも高速になります。それでも、ここで説明されているスクリプトレットの使用は避けてください。

プレゼンテーション層のテクノロジとしてJSPの代わりにFaceletsを使用する場合は、スクリプトレットを使用する必要はまったくありません。

私見ですが、JSTL(およびその他のタグ)を解析するための100または200ミリ秒のオーバーヘッドがアプリケーションに大きな影響を与えるとは思えません。

于 2013-02-23T23:00:34.417 に答える
0

forは言語構造であり<c:foreach>、単なるforループにコンパイルされないため、オーバーヘッドが発生します。JSTLタグは他のタグと同じように、コンテナによって実行され、コンテナはライフサイクルメソッドとコールバックメソッドを呼び出します。コンテナ(TomcatやWebLogicなど)で生成されたJSPのソースコードを見ると、単純なタグを使用すると多くのオーバーヘッドが発生することがわかります。

しかし、このオーバーヘッドは、データアクセス、ネットワーク、および...の遅延に匹敵するものではないと思います。したがって、このわずかな遅延を無視し、JSTLとタグを使用して、JSPをより読みやすく保守しやすくします。

更新しました:

ちなみに、JSTL(または他のタグライブラリ)を使用する場合、通常はJSP ELも使用するため、 ELの評価には少しオーバーヘッドがあります。ただし、これらのオーバーヘッドは、データアクセス、ネットワーク遅延、および...と比較してカウントされません。

于 2013-02-23T23:22:33.727 に答える