]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
shuf: avoid locking standard output when using --input-range
authorCollin Funk <collin.funk1@gmail.com>
Sat, 21 Feb 2026 08:06:01 +0000 (00:06 -0800)
committerCollin Funk <collin.funk1@gmail.com>
Sun, 22 Feb 2026 03:20:07 +0000 (19:20 -0800)
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.

NEWS
src/shuf.c

diff --git a/NEWS b/NEWS
index c509cbc1eaecc7f4f1659d305c99784a6122c325..cfa6b4abbe0821e752dfe74e1d1b764d171718b0 100644 (file)
--- 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.
 
index f87b85dd0fd8ba8b1181087454bfda55b051a8f0..948ee88f3d8bda3d4ad6ab1766b84ff8f16eb0c0 100644 (file)
@@ -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;
     }