From: Collin Funk Date: Sat, 21 Feb 2026 08:06:01 +0000 (-0800) Subject: shuf: avoid locking standard output when using --input-range X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=89735ea830b293d50a9323770d6089bac7324aab;p=thirdparty%2Fcoreutils.git shuf: avoid locking standard output when using --input-range Here is the throughput before this patch: # write_permuted_numbers $ ./src/shuf-prev -i 0-100000000 | pv -r > /dev/null [ 153MiB/s] # write_random_numbers $ timeout 10 ./src/shuf-prev -i 0-100000 -r | pv -r > /dev/null [78.6MiB/s] Here is the throughput after this patch: # write_permuted_numbers $ timeout 10 ./src/shuf -i 0-100000000 | pv -r > /dev/null [ 308MiB/s] # write_random_numbers $ timeout 10 ./src/shuf -i 0-100000 -r | pv -r > /dev/null [ 196MiB/s] * NEWS: Mention the performance improvement. * src/shuf.c (write_permuted_numbers, write_random_numbers): Prefer fputs and fputc which may be unlocked over printf which locks standard output. --- diff --git a/NEWS b/NEWS index c509cbc1ea..cfa6b4abbe 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,9 @@ GNU coreutils NEWS -*- outline -*- 'nl' now supports multi-byte --section-delimiter characters. + 'shuf -i' now operates up to two times faster on systems with unlocked stdio + functions. + 'wc -l' now operates up to three times faster on hosts that support Neon instructions. diff --git a/src/shuf.c b/src/shuf.c index f87b85dd0f..948ee88f3d 100644 --- a/src/shuf.c +++ b/src/shuf.c @@ -325,7 +325,9 @@ write_permuted_numbers (size_t n_lines, size_t lo_input, for (size_t i = 0; i < n_lines; i++) { unsigned long int n = lo_input + permutation[i]; - if (printf ("%lu%c", n, eolbyte) < 0) + char buf[INT_BUFSIZE_BOUND (uintmax_t)]; + if (fputs (umaxtostr (n, buf), stdout) < 0 + || fputc (eolbyte, stdout) < 0) return -1; } @@ -343,7 +345,9 @@ write_random_numbers (struct randint_source *s, size_t count, for (size_t i = 0; i < count; i++) { unsigned long int j = lo_input + randint_choose (s, range); - if (printf ("%lu%c", j, eolbyte) < 0) + char buf[INT_BUFSIZE_BOUND (uintmax_t)]; + if (fputs (umaxtostr (j, buf), stdout) < 0 + || fputc (eolbyte, stdout) < 0) return -1; }