Speed up uuid_out() by not relying on a StringInfo
authorMichael Paquier <michael@paquier.xyz>
Thu, 22 Feb 2024 01:02:55 +0000 (10:02 +0900)
committerMichael Paquier <michael@paquier.xyz>
Thu, 22 Feb 2024 01:02:55 +0000 (10:02 +0900)
Since the size of the string representation of an uuid is fixed, there
is no benefit in using a StringInfo.  This commit simplifies uuid_oud()
to not rely on a StringInfo, where avoiding the overhead of the string
manipulation makes the function substantially faster.

A COPY TO on a relation with one UUID attribute can show up to a 40%
speedup when the bottleneck is the COPY computation with uuid_out()
showing up at the top of the profiles (numbered measure here, Laurenz
has mentioned something closer to 20% faster runtimes), for example when
the data is fully in shared buffers or the OS cache.

Author: Laurenz Albe
Reviewed-by: Andres Freund, Michael Paquier
Description: https://postgr.es/m/679d5455cbbb0af667ccb753da51a475bae1eaed.camel@cybertec.at

src/backend/utils/adt/uuid.c

index 73dfd711c7311d8de69172a81292a23d18c9ba5b..2ca8fc6994300030db06204c8f9fe572128484bf 100644 (file)
@@ -53,10 +53,13 @@ uuid_out(PG_FUNCTION_ARGS)
 {
    pg_uuid_t  *uuid = PG_GETARG_UUID_P(0);
    static const char hex_chars[] = "0123456789abcdef";
-   StringInfoData buf;
+   char       *buf,
+              *p;
    int         i;
 
-   initStringInfo(&buf);
+   /* counts for the four hyphens and the zero-terminator */
+   buf = palloc(2 * UUID_LEN + 5);
+   p = buf;
    for (i = 0; i < UUID_LEN; i++)
    {
        int         hi;
@@ -68,16 +71,17 @@ uuid_out(PG_FUNCTION_ARGS)
         * ("-"). Therefore, add the hyphens at the appropriate places here.
         */
        if (i == 4 || i == 6 || i == 8 || i == 10)
-           appendStringInfoChar(&buf, '-');
+           *p++ = '-';
 
        hi = uuid->data[i] >> 4;
        lo = uuid->data[i] & 0x0F;
 
-       appendStringInfoChar(&buf, hex_chars[hi]);
-       appendStringInfoChar(&buf, hex_chars[lo]);
+       *p++ = hex_chars[hi];
+       *p++ = hex_chars[lo];
    }
+   *p = '\0';
 
-   PG_RETURN_CSTRING(buf.data);
+   PG_RETURN_CSTRING(buf);
 }
 
 /*