Optimize expandMacro() a bit, based on patch by Alexey Tourbin
authorPanu Matilainen <pmatilai@redhat.com>
Tue, 16 Apr 2013 07:45:56 +0000 (10:45 +0300)
committerPanu Matilainen <pmatilai@redhat.com>
Fri, 7 Jun 2013 09:22:24 +0000 (12:22 +0300)
- Avoid the expensive calloc() when creating a macro expansion buffer,
  malloc() suffices just as well as long as we initialize the first
  byte in the buffer. This is easily visible on wall-clock times.
- Avoid recalculating source string length: when caller doesn't
  pass slen, we always calculate the string length for creating
  a terminated copy, no need to redo it...
- Add a warning comment about the seemingly obvious optimization
  breaking macro undefining itself, this is starting to look like
  a recurring theme :)
(cherry picked from commit c012a7698537ac446b87d636d8d835ae0fe78fdb)

rpmio/macro.c

index 4979a47..0533771 100644 (file)
@@ -899,7 +899,12 @@ expandMacro(MacroBuf mb, const char *src, size_t slen)
     int chkexist;
     char *source = NULL;
 
-    /* Handle non-terminated substrings by creating a terminated copy */
+    /*
+     * Always make a (terminated) copy of the source string.
+     * Beware: avoiding the copy when src is known \0-terminated seems like
+     * an obvious opportunity for optimization, but doing that breaks
+     * a special case of macro undefining itself.
+     */
     if (!slen)
        slen = strlen(src);
     source = xmalloc(slen + 1);
@@ -908,8 +913,9 @@ expandMacro(MacroBuf mb, const char *src, size_t slen)
     s = source;
 
     if (mb->buf == NULL) {
-       size_t blen = MACROBUFSIZ + strlen(s);
-       mb->buf = xcalloc(blen + 1, sizeof(*mb->buf));
+       size_t blen = MACROBUFSIZ + slen;
+       mb->buf = xmalloc(blen + 1);
+       mb->buf[0] = '\0';
        mb->tpos = 0;
        mb->nb = blen;
     }