improve RouteImpl pathMatches: fast and less gc
On my jmh test regionMatches vs removeTrailing: fast over 70%(1.7X) and without create any new String
ref:
@@ -58,6 +58,7 @@ public class RouteImpl implements Route {
private boolean useNormalisedPath = true;
private Set<String> namedGroupsInRegex = new TreeSet<>();
private Pattern virtualHostPattern;
+ private boolean pathEndsWithSlash;
RouteImpl(RouterImpl router, int order) {
this.router = router;
@@ -378,7 +379,8 @@ public class RouteImpl implements Route {
if (exactPath) {
return pathMatchesExact(requestPath, thePath);
} else {
- if (thePath.endsWith("/") && requestPath.equals(removeTrailing(thePath))) {
+ if (pathEndsWithSlash && (requestPath.charAt(requestPath.length() - 1) == '/'
+ ? requestPath.equals(thePath) : thePath.regionMatches(0, requestPath, 0, requestPath.length()))) {
return true;
}
return requestPath.startsWith(thePath);
@@ -399,16 +401,12 @@ public class RouteImpl implements Route {
private boolean pathMatchesExact(String path1, String path2) {
// Ignore trailing slash when matching paths
- return removeTrailing(path1).equals(removeTrailing(path2));
+ final int idx1 = path1.length() - 1;
+ return pathEndsWithSlash ?
+ (path1.charAt(idx1) == '/' ? path1.equals(path2) : path2.regionMatches(0, path1, 0, path1.length()))
+ :(path1.charAt(idx1) != '/' ? path1.equals(path2) : path1.regionMatches(0, path2, 0, path2.length()));
}
- private String removeTrailing(String path) {
- int i = path.length();
- if (path.charAt(i - 1) == '/') {
- path = path.substring(0, i - 1);
- }
- return path;
- }
private void setPath(String path) {
// See if the path contains ":" - if so then it contains parameter capture groups and we have to generate
@@ -425,6 +423,7 @@ public class RouteImpl implements Route {
this.path = path.substring(0, path.length() - 1);
}
}
+ pathEndsWithSlash = this.path.endsWith("/");
}
private void setRegex(String regex) {
