question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

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.

See original GitHub issue

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.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:12 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
encircledcommented, Apr 9, 2020

Sure, I will prepare the PR later

0reactions
rstoyanchevcommented, Apr 24, 2020

As a side note, I’d like to point out that we’re aware that AntPathMatcher is not optimized for matching request path patterns (memory allocation, CPU). We’ve introduced PathPattern and PathPatternParser in Spring WebFlux since.

This implementation is not currently the default in Spring MVC as it’s a breaking change - but it’s a change we’re considering for future versions.

There is an issue for that now #24945.

Read more comments on GitHub >

github_iconTop Results From Across the Web

URL Pattern API - MDN Web Docs
The URL Pattern API defines a syntax that is used to create URL pattern matchers. These patterns can be matched against URLs or...
Read more >
Getting parts of a URL (Regex) - Stack Overflow
Beware that it doesn't work if the URL doesn't have a path after the domain -- e.g. http://www.example.com or if the path is...
Read more >
URL Matching with PathPattern in Spring MVC
Matching a String path to a String pattern makes it difficult to avoid URI encoding issues. For example should the incoming path be...
Read more >
Request Matching - WireMock
URLs can be matched either by equality or by regular expression. You also have a choice of whether to match just the path...
Read more >
Everything you need to know about Regular Expressions
The above pattern matches foo.csv , but does not match bar.txt or my_csv_file . Before you use regular expressions in your code, you...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found