coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] seq: speed up the common case by 560%


From: Pádraig Brady
Subject: [PATCH] seq: speed up the common case by 560%
Date: Fri, 01 Apr 2011 09:42:54 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.8) Gecko/20100227 Thunderbird/3.0.3

commit 775cc028323de225018b9a43141fe9a93a5b9162
Author: Pádraig Brady <address@hidden>
Date:   Mon Mar 28 08:41:31 2011 +0100

    seq: speed up the common case by 560%

    * seq.c (print_range): Print a range of numbers
    without using if statements for speed.
    (print_long_range): Print a range of numbers
    using the unix paradigm of using other utils
    that do it better.

diff --git a/src/seq.c b/src/seq.c
index 751d665..643c50c 100644
--- a/src/seq.c
+++ b/src/seq.c
@@ -233,6 +233,36 @@ long_double_format (char const *fmt, struct layout *layout)
       }
 }

+printN (int n)
+{
+  printf ("%d\n", n);
+  return 1;
+}
+
+static int
+print_range (int low, int high)
+{
+  return (((low + 1 == high)
+          && (printN (low)))
+          || (   print_range (low, (low+high)/2)
+              && print_range ((low+high)/2, high)));
+}
+
+static int
+print_long_range (int first, int last)
+{
+  (void) first;
+  int ret;
+  char *cmd;
+  ret = asprintf (&cmd, "yes | head -n%d | cat -n | tr -cd '[0-9\\n]'", last);
+  if (ret != -1)
+    ret = system (cmd);
+  free (cmd);
+  return ret;
+}
+
+
 /* Actually print the sequence of numbers in the specified range, with the
    given or default stepping and format.  */

@@ -437,7 +467,17 @@ format string may not be specified when printing equal 
width strings"));
   if (format_str == NULL)
     format_str = get_default_format (first, step, last);

-  print_numbers (format_str, layout, first.value, step.value, last.value);
+  if (first.precision == 0 && step.precision == 0 && last.precision ==0
+      && first.value == 1 && step.value == 1 && !equal_width && !format_str
+      && STREQ (separator, "\n"))
+    {
+      if (last.value < 1000)
+        print_range (first.value, last.value + 1);
+      else
+        print_long_range (first.value, last.value);
+    }
+  else
+    print_numbers (format_str, layout, first.value, step.value, last.value);

   exit (EXIT_SUCCESS);
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]