Author: markt
Date: Tue Mar  1 21:03:12 2016
New Revision: 1733154

URL: http://svn.apache.org/viewvc?rev=1733154&view=rev
Log:
Small performance improvement and add some notes on performance.
The gain probably wasn't worth the time spent on this but the code is no more 
complex and it is faster so it makes sense to keep it.

Modified:
    tomcat/trunk/java/org/apache/tomcat/util/buf/UriUtil.java
    tomcat/trunk/test/org/apache/tomcat/util/buf/TestUriUtil.java

Modified: tomcat/trunk/java/org/apache/tomcat/util/buf/UriUtil.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/buf/UriUtil.java?rev=1733154&r1=1733153&r2=1733154&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/buf/UriUtil.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/buf/UriUtil.java Tue Mar  1 
21:03:12 2016
@@ -19,12 +19,17 @@ package org.apache.tomcat.util.buf;
 import java.io.File;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.regex.Pattern;
 
 /**
  * Utility class for working with URIs and URLs.
  */
 public final class UriUtil {
 
+    private static Pattern PATTERN_EXCLAMATION_MARK = Pattern.compile("!/");
+    private static Pattern PATTERN_CARET = Pattern.compile("\\^/");
+    private static Pattern PATTERN_ASTERISK = Pattern.compile("\\*/");
+
     private UriUtil() {
         // Utility class. Hide default constructor
     }
@@ -100,15 +105,27 @@ public final class UriUtil {
 
 
     /*
+     * When testing on markt's desktop each iteration was taking ~1420ns when
+     * using String.replaceAll().
+     *
+     * Switching the implementation to use pre-compiled patterns and
+     * Pattern.matcher(input).replaceAll(replacement) reduced this by ~10%.
+     *
+     * Note: Given the very small absolute time of a single iteration, even for
+     *       a web application with 1000 JARs this is only going to add ~3ms.
+     *       It is therefore unlikely that further optimisation will be
+     *       necessary.
+     */
+    /*
      * Pulled out into a separate method in case we need to handle other 
unusual
      * sequences in the future.
      */
     private static String makeSafeForJarUrl(String input) {
         // Since "!/" has a special meaning in a JAR URL, make sure that the
         // sequence is properly escaped if present.
-        String tmp = input.replaceAll("!/", "%21/");
+        String tmp = 
PATTERN_EXCLAMATION_MARK.matcher(input).replaceAll("%21/");
         // Tomcat's custom jar:war: URL handling treats */ and ^/ as special
-        tmp = tmp.replaceAll("^/", "%5e/");
-        return tmp.replaceAll("\\*/", "%2a/");
+        tmp = PATTERN_CARET.matcher(tmp).replaceAll("%5e/");
+        return PATTERN_ASTERISK.matcher(tmp).replaceAll("%2a/");
     }
 }

Modified: tomcat/trunk/test/org/apache/tomcat/util/buf/TestUriUtil.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/buf/TestUriUtil.java?rev=1733154&r1=1733153&r2=1733154&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/util/buf/TestUriUtil.java (original)
+++ tomcat/trunk/test/org/apache/tomcat/util/buf/TestUriUtil.java Tue Mar  1 
21:03:12 2016
@@ -18,6 +18,7 @@ package org.apache.tomcat.util.buf;
 
 import java.io.File;
 import java.net.MalformedURLException;
+import java.net.URL;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -58,4 +59,29 @@ public class TestUriUtil {
         index = result.indexOf("^/");
         Assert.assertEquals(result, -1, index);
     }
+
+
+    // @Test /* Uncomment to test performance for different implementations. */
+    public void performanceTestBuildJarUrl() throws MalformedURLException {
+        File jarFile = new File("/patha/pathb^/pathc");
+
+        URL url = null;
+
+        int count = 1000000;
+
+        // Warm up
+        for (int i = 0; i < count / 10; i++) {
+            url = UriUtil.buildJarUrl(jarFile);
+        }
+
+        // Test
+        long start = System.nanoTime();
+        for (int i = 0; i < count / 10; i++) {
+            url = UriUtil.buildJarUrl(jarFile);
+        }
+        long duration = System.nanoTime() - start;
+
+        System.out.println("[" + count + "] iterations took [" +
+                duration + "] ns for [" + url + "]");
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to