Skip to content

Avoid using Regex for matching URL paths when possible as doing so causes more of the request time to be spent in regex then doing the API call itself. #24873

@LukeButters

Description

@LukeButters

Affects: I don't know of a version this does not affect.

Hi, profiling reveals that a bunch of time is spent in in this stack trace:

    at java.base@11.0.3/java.util.regex.Matcher.<init>(Matcher.java:248)
    at java.base@11.0.3/java.util.regex.Pattern.matcher(Pattern.java:1133)
    at org.springframework.util.AntPathMatcher$AntPathStringMatcher.matchStrings(AntPathMatcher.java:686)
    at org.springframework.util.AntPathMatcher.matchStrings(AntPathMatcher.java:421)
    at org.springframework.util.AntPathMatcher.doMatch(AntPathMatcher.java:218)
    at org.springframework.util.AntPathMatcher.match(AntPathMatcher.java:177)
    at org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getMatchingPattern(PatternsRequestCondition.java:258)
    at org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getMatchingPatterns(PatternsRequestCondition.java:223)
    at org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getMatchingCondition(PatternsRequestCondition.java:205)
    at org.springframework.web.servlet.mvc.method.RequestMappingInfo.getMatchingCondition(RequestMappingInfo.java:229)
    at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.getMatchingMapping(RequestMappingInfoHandlerMapping.java:93)
    at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.getMatchingMapping(RequestMappingInfoHandlerMapping.java:57)
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.addMatchingMappings(AbstractHandlerMethodMapping.java:428)
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:394)
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:368)
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:65)
    at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:401)
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1231)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1014)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)

I think this is trying to work out which API method to call and to do that it is matching the URL path against a regex. Regex is extremely slow, by using regex here it makes the APIs spend most of their time in this rather than doing the actual work. This is not good especially when we want to use spring to slice up an application served over many APIs e.g. micro services. I think a case in which this gets especially bad is when many APIs exist, I think this does a linear search :(.

One step towards not having all time spent in this regex matching would be to create simple matchers for some of the more trivial and common cases like those where the API method is not presenting a complex regex. I think some thought might need to go into this, you may want to collection the value of a bunch of @RequestMappings to find out what common styles of request mappings are in use.

I think this is looking at all @RequestMapping trying to find which ones match, perhaps what might also work is having the matcher defined as two sections a quick match which is fast to exclude (e.g. path length, starts with X etc) and if that matches then go on to the slow regex matching.

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: declinedA suggestion or change that we don't feel we should currently apply

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions