diff mbox

builtin: Fix echo performance regression

Message ID 20180325035036.GA5214@gondor.apana.org.au (mailing list archive)
State Accepted
Delegated to: Herbert Xu
Headers show

Commit Message

Herbert Xu March 25, 2018, 3:50 a.m. UTC
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 <herbert@gondor.apana.org.au>
diff mbox

Patch

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