]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
OPTIM: http: improve parsing performance of long URIs
authorWilly Tarreau <w@1wt.eu>
Sat, 5 Nov 2016 16:52:06 +0000 (17:52 +0100)
committerWilly Tarreau <w@1wt.eu>
Sat, 5 Nov 2016 17:00:35 +0000 (18:00 +0100)
Searching the trailing space in long URIs takes some time. This can
happen especially on static files and some blogs. By skipping valid
character ranges by 32-bit blocks, it's possible to increase the
HTTP performance from 212k to 216k req/s on requests features a
100-character URI, which is an increase of 2%. This is done for
architectures supporting unaligned accesses (x86_64, x86, armv7a).
There's only a 32-bit version because URIs are rarely long and very
often short, so it's more efficient to limit the systematic overhead
than to try to optimize for the rarest requests.

src/proto_http.c

index c9f38b1b12790f535e266576d4dd920fae4e3244..36428b164024aaf929b081fd32bcd7bf5b15403e 100644 (file)
@@ -1519,8 +1519,25 @@ const char *http_parse_reqline(struct http_msg *msg,
 
        case HTTP_MSG_RQURI:
        http_msg_rquri:
+#if defined(__x86_64__) ||                                             \
+    defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || \
+    defined(__ARM_ARCH_7A__)
+               /* speedup: skip bytes not between 0x21 and 0x7e inclusive */
+               while (ptr <= end - sizeof(int)) {
+                       int x = *(int *)ptr - 0x21212121;
+                       if (x & 0x80808080)
+                               break;
+
+                       x -= 0x5e5e5e5e;
+                       if (!(x & 0x80808080))
+                               break;
+
+                       ptr += sizeof(int);
+               }
+#endif
+       http_msg_rquri2:
                if (likely((unsigned char)(*ptr - 33) <= 93)) /* 33 to 126 included */
-                       EAT_AND_JUMP_OR_RETURN(http_msg_rquri, HTTP_MSG_RQURI);
+                       EAT_AND_JUMP_OR_RETURN(http_msg_rquri2, HTTP_MSG_RQURI);
 
                if (likely(HTTP_IS_SPHT(*ptr))) {
                        msg->sl.rq.u_l = ptr - msg_start - msg->sl.rq.u;