seq: 70x faster for non-negative whole numbers and incr==1
authorJim Meyering <meyering@redhat.com>
Thu, 13 Sep 2012 16:09:49 +0000 (18:09 +0200)
committerJim Meyering <meyering@redhat.com>
Fri, 14 Sep 2012 11:34:51 +0000 (13:34 +0200)
commit77f89d014be68e42de5107aee0be95d18ee1735c
tree78c3743570816ce0d6be01f958a197968e37b76b
parent0b4abe7b42a8236f9d75c4e6f9ddb30111b63990
seq: 70x faster for non-negative whole numbers and incr==1

Handle non-negative whole numbers robustly and efficiently when
the increment is 1 and when no format-changing option is specified.
On the correctness front, for very large numbers, seq now works fine:

    $ b=1000000000000000000000000000
    $ src/seq ${b}09 ${b}11
    100000000000000000000000000009
    100000000000000000000000000010
    100000000000000000000000000011

while the old one would infloop, printing garbage:

    $ seq ${b}09 ${b}11 | head -2
    99999999999999999997315645440
    99999999999999999997315645440

The new code is much more efficient, too:
Old vs new: 55.81s vs 0.82s

  $ env time --f=%e seq $((10**8)) > /dev/null
  55.81
  $ env time --f=%e src/seq $((10**8)) > /dev/null
  0.82

* seq.c (incr): New function, inspired by the one in cat.c.
(cmp, seq_fast): New functions, inspired by code in nt-factor
by Torbjörn Granlund and Niels Möller.
(trim_leading_zeros): New function, without which cmp would malfunction.
(all_digits_p): New function.
(main): Hoist the format_str-vs-equal_width check to precede first
treatment of operands, and insert code to call seq_fast when possible.
* NEWS (Bug fixes): Mention the correctness fix.
(Improvements): Mention the speed-up.
* tests/misc/seq.pl: Exercise the new code.

Improved by: Bernhard Voelker.
http://thread.gmane.org/gmane.comp.gnu.coreutils.general/3340
NEWS
src/seq.c
tests/misc/seq.pl