I instrumented apr_pstrcat and found that, in Apache 2.0, the number of
strings it's asked to concatenate is 6 or less 99+% of the time.

apr_pstrcat does two passes through its args: one to compute the
length, a second to do the copying.  This patch adds a buffer to
save the lengths of the first 6 args so that the second pass
doesn't need to another strlen on them.  (If you pass in more than
6 strings to concatenate, this optimization just gets applied to the
first 6.)

--Brian

Index: srclib/apr/strings/apr_strings.c
===================================================================
RCS file: /home/cvspublic/apr/strings/apr_strings.c,v
retrieving revision 1.20
diff -u -r1.20 apr_strings.c
--- srclib/apr/strings/apr_strings.c    2001/07/26 03:11:00     1.20
+++ srclib/apr/strings/apr_strings.c    2001/09/27 01:27:06
@@ -110,6 +110,9 @@
 APR_DECLARE_NONSTD(char *) apr_pstrcat(apr_pool_t *a, ...)
 {
     char *cp, *argp, *res;
+    static const int MAX_SAVED_LENGTHS = 6;
+    apr_size_t saved_lengths[MAX_SAVED_LENGTHS];
+    int nargs = 0;
 
     /* Pass one --- find length of required string */
 
@@ -119,7 +122,11 @@
     va_start(adummy, a);
 
     while ((cp = va_arg(adummy, char *)) != NULL) {
-        len += strlen(cp);
+        apr_size_t cplen = strlen(cp);
+        if (nargs < MAX_SAVED_LENGTHS) {
+            saved_lengths[nargs++] = cplen;
+        }
+        len += cplen;
     }
 
     va_end(adummy);
@@ -133,8 +140,14 @@
 
     va_start(adummy, a);
 
+    nargs = 0;
     while ((argp = va_arg(adummy, char *)) != NULL) {
-        len = strlen(argp);
+        if (nargs < MAX_SAVED_LENGTHS) {
+            len = saved_lengths[nargs++];
+        }
+        else {
+            len = strlen(argp);
+        }
         memcpy(cp, argp, len);
         cp += len;
     }

Reply via email to