Add fast path for simple URL parsing
authorGabriel Wicke <wicke@wikidev.net>
Tue, 1 Jul 2014 19:28:49 +0000 (12:28 -0700)
committerFedor Indutny <fedor@indutny.com>
Thu, 31 Jul 2014 18:56:46 +0000 (22:56 +0400)
This patch adds a fast path for parsing of simple path-only URLs, as commonly
found in HTTP requests received by a server.

Benchmark results [ms], before / after patch:
/foo/bar              0.008956   0.000418 (fast path used)
http://example.com/   0.011426   0.011437 (normal slow path, no change)

In a simple 'ab' benchmark of a single-threaded web server, this patch
increases the request rate from around 6400 to 7400 req/s.

Reviewed-By: Fedor Indutny <fedor@indutny.com>
lib/url.js

index 292ce33..f0be09c 100644 (file)
@@ -51,6 +51,9 @@ function Url() {
 var protocolPattern = /^([a-z0-9.+-]+:)/i,
     portPattern = /:[0-9]*$/,
 
+    // Special case for a simple path URL
+    simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,
+
     // RFC 2396: characters reserved for delimiting URLs.
     // We actually just auto-escape these.
     delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
@@ -119,6 +122,25 @@ Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
   // This is to support parse stuff like "  http://foo.com  \n"
   rest = rest.trim();
 
+  if (!slashesDenoteHost && hashSplit.length === 1) {
+    // Try fast path regexp
+    var simplePath = simplePathPattern.exec(rest);
+    if (simplePath) {
+      this.path = rest;
+      this.href = rest;
+      this.pathname = simplePath[1];
+      if (simplePath[2]) {
+        this.search = simplePath[2];
+        if (parseQueryString) {
+          this.query = querystring.parse(this.search);
+        } else {
+          this.query = this.search.substr(1);
+        }
+      }
+      return this;
+    }
+  }
+
   var proto = protocolPattern.exec(rest);
   if (proto) {
     proto = proto[0];