There is 2 improvements: * remove useless uuid_unpack, * directly print the hexa format from memory without using printf we can do this as the bytes order is the network byte order https://tools.ietf.org/html/rfc4122#section-4.1.2 even the spatially unique node identifier(the last 6 bytes) The improvement is important, some results for 1000000 uuid_unparse calls: Little Endian Ubuntu: before took 382623 us after took 36740 us Big Endian OpenBSD: before took 3138172 us after took 180116 us Signed-off-by: Aurelien LAJOIE <orel@xxxxxxxxx> --- libuuid/src/unparse.c | 45 ++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/libuuid/src/unparse.c b/libuuid/src/unparse.c index a95bbb042..0e7e8eae4 100644 --- a/libuuid/src/unparse.c +++ b/libuuid/src/unparse.c @@ -36,41 +36,38 @@ #include "uuidP.h" -static const char *fmt_lower = - "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"; +static char const hexdigits_lower[16] = "0123456789abcdef"; +static char const hexdigits_upper[16] = "0123456789ABCDEF"; -static const char *fmt_upper = - "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"; - -#ifdef UUID_UNPARSE_DEFAULT_UPPER -#define FMT_DEFAULT fmt_upper -#else -#define FMT_DEFAULT fmt_lower -#endif - -static void uuid_unparse_x(const uuid_t uu, char *out, const char *fmt) +static void uuid_fmt(const uuid_t uuid, char *buf, char const fmt[restrict]) { - struct uuid uuid; + char *p = buf; - uuid_unpack(uu, &uuid); - sprintf(out, fmt, - uuid.time_low, uuid.time_mid, uuid.time_hi_and_version, - uuid.clock_seq >> 8, uuid.clock_seq & 0xFF, - uuid.node[0], uuid.node[1], uuid.node[2], - uuid.node[3], uuid.node[4], uuid.node[5]); + for (int i = 0; i < 16; i++) { + if (i == 4 || i == 6 || i == 8 || i == 10) { + *p++ = '-'; + } + size_t tmp = uuid[i]; + *p++ = fmt[tmp >> 4]; + *p++ = fmt[tmp & 15]; + } + *p = '\0'; } void uuid_unparse_lower(const uuid_t uu, char *out) { - uuid_unparse_x(uu, out, fmt_lower); + uuid_fmt(uu, out, hexdigits_lower); } void uuid_unparse_upper(const uuid_t uu, char *out) { - uuid_unparse_x(uu, out, fmt_upper); + uuid_fmt(uu, out, hexdigits_upper); } +#ifdef UUID_UNPARSE_DEFAULT_UPPER void uuid_unparse(const uuid_t uu, char *out) -{ - uuid_unparse_x(uu, out, FMT_DEFAULT); -} + __attribute__((alias("uuid_unparse_upper"))); +#else +void uuid_unparse(const uuid_t uu, char *out) + __attribute__((alias("uuid_unparse_lower"))); +#endif -- 2.20.1