From 42b730b034eebd0e9da4aa014785a3ee5de436be Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 25 Mar 2018 11:50:36 +0800 Subject: builtin: Fix echo performance regression The commit d6c0e1e2ffbf7913ab69d51cc794d48d41c8fcb1 ("[BUILTIN] Handle embedded NULs correctly in printf") caused a performance regression in the echo built-in because every echo call now goes through the printf %b slow path where the string is always printed twice to ensure the space padding is correct in the presence of NUL characters. In fact this regression applies to printf %b as well. This is easily fixed by making printf %b take the fast path when no precision/field width modifiers are present. This patch also changes the second strchurnul call to strspn which generates slightly better code. Signed-off-by: Herbert Xu --- src/bltin/printf.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/bltin/printf.c b/src/bltin/printf.c index ec7c8c2..eaf14b6 100644 --- a/src/bltin/printf.c +++ b/src/bltin/printf.c @@ -98,20 +98,25 @@ static int print_escape_str(const char *f, int *param, int *array, char *s) int total; setstackmark(&smark); - done = conv_escape_str(s, &p); - q = stackblock(); - len = p - q; + done = conv_escape_str(s, &q); + p = stackblock(); + len = q - p; + total = len - 1; + + if (f[1] == 's') + goto easy; - p = makestrspace(len, p); - memset(p, 'X', len - 1); - p[len - 1] = 0; + p = makestrspace(len, q); + memset(p, 'X', total); + p[total] = 0; q = stackblock(); total = ASPF(&p, f, p); len = strchrnul(p, 'X') - p; - memcpy(p + len, q, strchrnul(p + len, ' ') - (p + len)); + memcpy(p + len, q, strspn(p + len, "X")); +easy: out1mem(p, total); popstackmark(&smark); -- cgit 1.4.1