[BLOSSOM-195] Performance improvements for forward and include wrappers Created: 14/Nov/14  Updated: 09/Jul/15  Resolved: 19/Dec/14

Status: Closed
Project: Blossom
Component/s: None
Affects Version/s: None
Fix Version/s: 2.0.7, 3.0.5

Type: Improvement Priority: Neutral
Reporter: Tobias Mattsson Assignee: Tobias Mattsson
Resolution: Fixed Votes: 0
Labels: support
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: File magnolia-module-blossom-3.0.5-BLOSSOM-195.jar    
Issue Links:
causality
duplicate
is duplicated by BLOSSOM-194 Blossom SpecialAttributeRequestWrappe... Closed
is duplicated by BLOSSOM-187 Performance problem related to Specia... Closed
relation
is related to BLOSSOM-130 Nesting the same JSP + Performance im... Closed
Template:
Acceptance criteria:
Empty
Task DoD:
[ ]* Doc/release notes changes? Comment present?
[ ]* Downstream builds green?
[ ]* Solution information and context easily available?
[ ]* Tests
[ ]* FixVersion filled and not yet released
[ ]  Architecture Decision Record (ADR)

 Description   

The forward and include wrappers simulate servlet container dispatch operations by overriding path element getters and adding the appropriate request attributes. To properly implement these they need to adapt when a real dispatch is performed. When the servlet container performs a dispatch it doesn't add a wrapper at the front of the request chain, instead it changes the original request at the back of the chain (or inserts a wrapper inside the chain just after the original one). To detect this the Blossom wrappers probes the chain behind them to figure out if something has changed. They need to know this in order to decide whether they should override attributes and path elements.

While these calls are quick and simple they're called very frequently and need to be as fast as possible.

With this issue we should take the same approach for the forward wrapper. Other possible performance improvements should be investigated as well.

  • ForwardRequestWrapper should stop overriding path elements when it sees a forward dispatch. This will remove the need to probe backwards for all path elements.
  • SpecialAttributeRequestWrapper should not probe backwards to test for changed attributes since this is no longer necessary.

In the unusual situation where a forward is performed after an include, which is supported by containers, no include attributes should be visible

  • When applied ForwardRequestWrapper should disable all IncludeRequestWrappers already in chain to hide their attributes (bugfix).
  • IncludeRequestWrapper should stop exposing attributes when it sees a forward dispatch, they must not be visible (bugfix).

In BLOSSOM-130 a major improvement was made by letting the include wrapper switch itself off when a real include dispatch happens. This works as long as a real dispatch is performed between additions of IncludeRequestWrappers. This is the case when using JSPs but not for Freemarker or Thymeleaf. We should therefor do the same thing explicitly when adding an IncludeRequestWrapper.

  • When applied IncludeRequestWrapper should disable all other IncludeRequestWrappers already in chain since they will have no effect anyway.

In addition these performance enhancements should be done.

  • When applied ForwardRequestWrapper should disable all other ForwardRequestWrappers already in chain since they will have no effect anyway.
  • SpecialAttributeRequestWrapper should have slots only for attributes that are actually overridden.
  • SpecialAttributeRequestWrapper should test with a prefix on attribute name before testing its overrides.
  • SpecialAttributeRequestWrapper should skip wrapping attribute name enumeration when disabled.
  • SpecialAttributeRequestWrapper should have attribute name enumeration methods inlined.


 Comments   
Comment by Tobias Mattsson [ 14/Nov/14 ]

Results from performance measurements.

Eighty million calls per test, with 2 forward wrappers followed by 5 include wrappers.

                                | Old code               | New code               |
Test                  Calls     | Duration    Time/call  | Duration    Time/call  | Improvement
--------------------------------+------------------------+------------------------+-------------
getAttribute #1       80000000     9390 ms    117.38 ns     6384 ms     79.80 ns        47.09 %
getAttribute #2       80000000    10079 ms    125.99 ns     7580 ms     94.75 ns        32.97 %
getAttribute #3       80000000     9367 ms    117.09 ns     2602 ms     32.53 ns       259.99 %
getRequestUri         80000000    29161 ms    364.51 ns     2062 ms     25.78 ns      1314.21 %
getContextPath        80000000    32094 ms    401.17 ns     2038 ms     25.47 ns      1474.78 %
getServletPath        80000000    30715 ms    383.94 ns     2013 ms     25.16 ns      1425.83 %
getPathInfo           80000000    32324 ms    404.05 ns     2004 ms     25.05 ns      1512.97 %
setAttribute          80000000    12514 ms    156.42 ns     6745 ms     84.31 ns        85.53 %
removeAttribute       80000000    12298 ms    153.73 ns     6029 ms     75.36 ns       103.98 %
getAttributeNames     80000000    64890 ms    811.13 ns    24393 ms    304.91 ns       166.02 %


getAttribute #1 = queries attribute from initial request
getAttribute #2 = queries forward attribute
getAttribute #3 = queries include attribute
getAttributeNames = acquires and loops enumeration

Generated at Sun Feb 11 23:31:05 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.