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

            Bug ID: 68596
           Summary: Remaining overhead in
                    javax.el.CompositeELResolver.convertToType
           Product: Tomcat 9
           Version: 9.0.85
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Jasper
          Assignee: dev@tomcat.apache.org
          Reporter: jeng...@amazon.com
  Target Milestone: -----

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

This issue was identified in production after deploying the fix for
https://bz.apache.org/bugzilla/show_bug.cgi?id=68119 and is an opportunity to
further improve the original hotspot.

Production data showed the other issue generated approximately a 2/3rds
reduction in the cost of javax.el.CompositeELResolver.convertToType; this is
less than predicted because of an overlooked virtual call:

public Object convertToType(ELContext context, Object obj, Class<?> type) {
    context.setPropertyResolved(false);
    ...
}

context can be of type ELContextImpl, ELContextWrapper, EvaluationContext, or
StandardELContext so this method triggers an invokevirtual.

My tests associated with the previous issue only included one type of ELContext
and the method was effectively final, allowing the JIT to eliminate the lookup.
 The fresh test attached to this ticket demonstrates the performance difference
when one ELContext subclass is used versus three, where each subclass' code is
identical.  On my PC the old-style test (one subclass) finished in
approximately 80ms but the new one (three subclasses) finishes in about 175ms.

The test also shows something else: commenting out
"context.setPropertyResolved(false);" in
RevisedCompositeELResolver.convertToType() causes the test to finish several
orders of magnitude faster.  I assume the JIT converts the method to a no-op.

The potential solutions I see are:
1. Eliminate the seemingly-unnecessary call to setPropertyResolved(false).  As
far as I can tell, the field is already false when convertToType() is called,
so this is a safe removal.
2. Create a final method on ELContext that somehow does the same work.  I
implemented a final method on ELContext that returned a boolean
"needsToSetPropertyResolved", which was set by the constructor.  This matched
the near-zero performance, however it required changes to each subclass, and
looks pretty hacky.

I'm hoping #1 is a good option.  :)

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