https://bz.apache.org/bugzilla/show_bug.cgi?id=69338

            Bug ID: 69338
           Summary: Overhead in El processing (AST*)
           Product: Tomcat 9
           Version: 9.0.x
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: EL
          Assignee: dev@tomcat.apache.org
          Reporter: jeng...@amazon.com
  Target Milestone: -----

Created attachment 39873
  --> https://bz.apache.org/bugzilla/attachment.cgi?id=39873&action=edit
Speed test

I received a report of a minor change to an EL expression causing a latency
penalty and, upon investigation, discovered some ways to simplify the execution
and reduce the effort required to evaluate EL.  I'm not convinced the report
was accurate but these are nevertheless good changes.

The specific change was adding a branch to an if statement, along these lines:

<c:if test="${not empty myNewAttribute
                && existingClause1
                && existingClause2
                && existingClause3
                && existingClause4}">



First - the expression "${not empty myNewAttribute}" is turned into five Node
instances: AstCompositeExpression, AstDynamicExpression, AstNot, AstEmpty, and
AstIdentifier. As noted previously, each call to getValue() on each node
triggers a virtual method lookup, so is more expensive than it looks.  Three of
the Nodes also rely on type coercion (AstCompositeExpression, AstNot,
AstEmpty).  Small EL changes such as the report I received can increase this
node depth and therefore noticeably increase the EL processing time. 
Suggestion: create an AstNotEmpty node to handle the frequent case of ${not
empty <whatever>}.  This will eliminate one Node and only attempt one Boolean
coercion rather than two.

Second - the use of multiple "&&" clauses results in a series of nested AstAnd.
 Each instance adds its own overhead and produces its own Boolean result... and
each parent AstAnd coerces that Boolean into another Boolean.  A
more-than-binary AstAnd would eliminate several layers of Nodes and the
associated coercion.

I've attached the usual standalone perf test, demonstrating a 25% deceleration
when the extra statement is added.  This is linear and therefore expected...
however the test is unusually memory sensitive (I run it with -Xmx3g) so there
may be some kind of effect there.

I expect these changes to reduce the processing time of any EL expression with
2+ "&&" clauses, as well as any expression using "not empty".

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to