coreutils
[Top][All Lists]
Advanced

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

Re: 70x speed-up for seq's common cases


From: Jim Meyering
Subject: Re: 70x speed-up for seq's common cases
Date: Fri, 14 Sep 2012 22:26:41 +0200

Pádraig Brady wrote:
...
> How about the attached follow up to enable the
> fast code in more cases?

Thanks!
I much prefer to honor --separator=S and your adjustment to use optind.

...
> Subject: [PATCH] seq: enable the fast integer printing code in more cases
>
> * src/seq.c (main): Adjust the initial arbitrary precision
> seq_fast enablement checks to be more maintainable, and
> a little more general, by allowing single character
> separators to use seq_fast.
> Also Check again after the number arguments are processed,

s/C/c/

> to see if we can still use seq_fast, which while not
> allowing arbitarly large integers, it will handle
> integers of the form 0x20 or 10E10 etc.
> ---
>  src/seq.c |   30 +++++++++++++++++++++++-------
>  1 files changed, 23 insertions(+), 7 deletions(-)
>
> diff --git a/src/seq.c b/src/seq.c
> index cedd25d..7ffd95f 100644
> --- a/src/seq.c
> +++ b/src/seq.c
> @@ -417,7 +417,7 @@ seq_fast (char const *a, char const *b)
>          {
>            incr (&p, &p_len);
>            z = mempcpy (z, p, p_len);
> -          *z++ = '\n';
> +          *z++ = *separator;
>            if (buf_end - n - 1 < z)
>              {
>                fwrite (buf, z - buf, 1, stdout);
> @@ -536,13 +536,13 @@ main (int argc, char **argv)
>       - integer end
>       - increment == 1 or not specified [FIXME: relax this, eventually]
>       then use the much more efficient integer-only code.  */
> -  if (format_str == NULL
> -      && all_digits_p (argv[1])
> -      && (n_args == 1 || all_digits_p (argv[2]))
> -      && (n_args < 3 || STREQ ("1", argv[3])))
> +  if (all_digits_p (argv[optind])
> +      && (n_args == 1 || all_digits_p (argv[optind + 1]))
> +      && (n_args < 3 || STREQ ("1", argv[optind + 2]))
> +      && !equal_width && !format_str && strlen (separator) == 1)
>      {
> -      char const *s1 = n_args == 1 ? "1" : argv[1];
> -      char const *s2 = n_args == 1 ? argv[1] : argv[2];
> +      char const *s1 = n_args == 1 ? "1" : argv[optind];
> +      char const *s2 = n_args == 1 ? argv[optind] : argv[optind + 1];
>        if (seq_fast (s1, s2))
>          exit (EXIT_SUCCESS);
>
> @@ -563,6 +563,22 @@ main (int argc, char **argv)
>          }
>      }
>
> +  if (first.precision == 0 && step.precision == 0 && last.precision == 0
> +      && 0 <= first.value && step.value == 1 && 0 <= last.value
> +      && !equal_width && !format_str && strlen (separator) == 1)
> +    {
> +      char *s1;
> +      char *s2;
> +      if (asprintf (&s1, "%0.Lf", first.value) < 0)
> +        xalloc_die ();
> +      if (asprintf (&s2, "%0.Lf", last.value) < 0)
> +        xalloc_die ();
> +      if (seq_fast (s1, s2))

Not sure if it's worth freeing here, since we're about to exit.
If so, it'd be guarded by IF_LINT.

> +        exit (EXIT_SUCCESS);

However, here, we should free both s1 and s2.

> +      /* Upon any failure, let the more general code deal with it.  */
> +    }
> +
>    if (format_str == NULL)
>      format_str = get_default_format (first, step, last);

With those addressed,
ACK!



reply via email to

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