Affects: Spring web 4.2+, 5.x (confirmed, possibly others)
A large, publicly-facing application receives more than 100 request parameters (don't ask) and the growing runtime of ServletRequestDataBinder has exposed an inefficiency: for each parameter, AbstractNestablePropertyAccessor.processLocalProperty() throws an exception, which is caught by AbstractPropertyAccessor.setPropertyValues(). This exception is then discarded because "ignoreUnknown" is true, and life goes on.
Throwing exceptions is an expensive operation because of the need to fill in stack traces (Throwable.fillInStackTrace) and this generates significant wasted effort. Modifying ServletRequestDataBinder.bind() to mark each PropertyValue as optional eliminates this penalty while maintaining the same functional behavior. Custom benchmarking shows a 93% reduction in cpu and clock time (21 vs. 350).
Workarounds are difficult because ServletRequestDataBinder is accessed via a chain of hard-coded references, plus our application uses the subclass ExtendedServletRequestDataBinder. The best option I've found so far is to use a custom bean factory to override the requestMappingHandlerAdapter bean (declared in WebMvcConfigurationSupport.requestMappingHandlerAdapter()) and make a subclass that overrides createDataBinderFactory, etc. "Convoluted" and "ugly" are good descriptions of those solution.
Comment From: jengebr
@jhoeller thank you for the fast turnaround! Is it possible to backport this to 4.3.x?
Comment From: jhoeller
I'll see what we can do in terms of backports. Depending on the eventual shape of the Abstract(Nestable)PropertyAccessor
revision, we may be able to easily backport it all the way down to 4.3.x indeed.
For a start, we got immediate 5.3.1 and 5.2.11 releases coming on Nov 10, so those will be the first where such a revision can be released. 5.1.20, 5.0.20 and 4.3.20 releases are subsequently scheduled for December.
Comment From: jengebr
Excellent, thank you! I appreciate anything you can do, and I understand your priorities. Good luck with the releases!
Comment From: jhoeller
This is available in all backport branches as well now: from 5.2.11.BUILD-SNAPSHOT
down to 4.3.30.BUILD-SNAPSHOT
(https://repo.spring.io/snapshot/org/springframework/spring-framework-bom/). Please give it an early try in a test scenario and let me know whether you're seeing the CPU efficiency improvement that you're expecting here...