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;
}