Subject: Re: bin/36092: algorithmic inefficiency in bin/test/test.c:t_lex
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,>
From: B K <mtbakerguy@yahoo.com>
List: netbsd-bugs
Date: 03/27/2007 22:30:02
The following reply was made to PR bin/36092; it has been noted by GNATS.
From: B K <mtbakerguy@yahoo.com>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: bin/36092: algorithmic inefficiency in bin/test/test.c:t_lex
Date: Tue, 27 Mar 2007 14:25:10 -0700 (PDT)
Hi Christos--
H'mmm, significantly improved performance without
sacrificing readability versus significantly improved
performance and camaro on blocks ugly.
Definitely an improvement.
--Brad
--- Christos Zoulas <christos@zoulas.com> wrote:
> The following reply was made to PR bin/36092; it has
> been noted by GNATS.
>
> From: christos@zoulas.com (Christos Zoulas)
> To: gnats-bugs@NetBSD.org, gnats-admin@netbsd.org,
> netbsd-bugs@netbsd.org
> Cc:
> Subject: Re: bin/36092: algorithmic inefficiency in
> bin/test/test.c:t_lex
> Date: Tue, 27 Mar 2007 12:54:24 -0400
>
> On Mar 27, 5:10am, mtbakerguy@yahoo.com
> (mtbakerguy@yahoo.com) wrote:
> -- Subject: bin/36092: algorithmic inefficiency in
> bin/test/test.c:t_lex
>
> | >Number: 36092
> | >Category: bin
> | >Synopsis: algorithmic inefficiency in
> bin/test/test.c:t_lex
> | >Confidential: no
> | >Severity: serious
> | >Priority: medium
> | >Responsible: bin-bug-people
> | >State: open
> | >Class: change-request
> | >Submitter-Id: net
> | >Arrival-Date: Tue Mar 27 05:10:00 +0000 2007
> | >Originator: Knotwell
> | >Release: 3.1
> | >Organization:
> | home
> | >Environment:
> | NetBSD bradwkstn 3.1 NetBSD 3.1 (GENERIC.PROF)
> #7: Thu Dec 14 21:54:41 PST 2006
>
root@bradwkstn:/usr/src/usr/src/sys/arch/i386/compile/GENERIC.PROF
> i386
> | >Description:
> | While profiling /bin/sh for fun, I noticed
> several things:
> |
> | o the test builtin is *extremely* expensive
> with massive calls to strcmp in the t_lex function.
> Specifically, it does linear walks of the operations
> to do a match.
> | o profiling /bin/sh is difficult because
> bin/sh/trap.c:exitshell uses _exit instead of exit
> (NB: this isn't a bug but probably belongs in a
> README somewhere)
> | o arithmetic operations are also more
> expensive than they need to be since there are two
> calls made to ioctl (via isatty) when
> arith_lex_reset is called. In my limited testing, I
> commented out the YY_NEW_FILE stanza and cut the
> number of syscalls substantially in a shell doing a
> large amount of arithmetic.
> |
> | At this cost of some codespace as well as
> readability*, I created a substantially improved
> parser for the test operations that dropped strcmp
> and t_lex off the profiler (almost) entirely. On a
> shell doing a significant number of boolean
> comparisons, I cut the run time by approximately
> 15%.
> |
> | I've attached a diff below as well as a small
> shell that I used to validate the change (I noticed
> TEST.csh as I was preparing the diff).
> |
> | *unfortunately, my change loses the data-driven
> clarity of the original code and it wasn't obvious
> to me how you'd get a data-driven solution nearly as
> efficient as mine. There's probably a simpler and
> more elegant solution but code review's difficult on
> a home project.
>
> How about this?
>
> christos
>
> Index: test.c
>
>
===================================================================
> RCS file: /cvsroot/src/bin/test/test.c,v
> retrieving revision 1.30
> diff -u -u -r1.30 test.c
> --- test.c 24 Sep 2006 13:24:08 -0000 1.30
> +++ test.c 27 Mar 2007 16:53:02 -0000
> @@ -95,50 +95,60 @@
> PAREN
> };
>
> -static struct t_op {
> +struct t_op {
> const char *op_text;
> short op_num, op_type;
> -} const ops [] = {
> - {"-r", FILRD, UNOP},
> - {"-w", FILWR, UNOP},
> - {"-x", FILEX, UNOP},
> - {"-e", FILEXIST,UNOP},
> - {"-f", FILREG, UNOP},
> - {"-d", FILDIR, UNOP},
> - {"-c", FILCDEV,UNOP},
> - {"-b", FILBDEV,UNOP},
> - {"-p", FILFIFO,UNOP},
> - {"-u", FILSUID,UNOP},
> - {"-g", FILSGID,UNOP},
> - {"-k", FILSTCK,UNOP},
> - {"-s", FILGZ, UNOP},
> - {"-t", FILTT, UNOP},
> - {"-z", STREZ, UNOP},
> - {"-n", STRNZ, UNOP},
> - {"-h", FILSYM, UNOP}, /* for backwards compat */
> - {"-O", FILUID, UNOP},
> - {"-G", FILGID, UNOP},
> - {"-L", FILSYM, UNOP},
> - {"-S", FILSOCK,UNOP},
> - {"=", STREQ, BINOP},
> - {"!=", STRNE, BINOP},
> - {"<", STRLT, BINOP},
> - {">", STRGT, BINOP},
> - {"-eq", INTEQ, BINOP},
> - {"-ne", INTNE, BINOP},
> - {"-ge", INTGE, BINOP},
> - {"-gt", INTGT, BINOP},
> - {"-le", INTLE, BINOP},
> - {"-lt", INTLT, BINOP},
> - {"-nt", FILNT, BINOP},
> - {"-ot", FILOT, BINOP},
> - {"-ef", FILEQ, BINOP},
> +};
> +
> +static const struct t_op cop[] = {
> {"!", UNOT, BUNOP},
> - {"-a", BAND, BBINOP},
> - {"-o", BOR, BBINOP},
> {"(", LPAREN, PAREN},
> {")", RPAREN, PAREN},
> - {0, 0, 0}
> + {"<", STRLT, BINOP},
> + {"=", STREQ, BINOP},
> + {">", STRGT, BINOP},
> +};
> +
> +static const struct t_op cop2[] = {
> + {"!=", STRNE, BINOP},
> +};
> +
> +static const struct t_op mop3[] = {
> + {"ef", FILEQ, BINOP},
> + {"eq", INTEQ, BINOP},
> + {"ge", INTGE, BINOP},
> + {"gt", INTGT, BINOP},
> + {"le", INTLE, BINOP},
> + {"lt", INTLT, BINOP},
> + {"ne", INTNE, BINOP},
> + {"nt", FILNT, BINOP},
> + {"ot", FILOT, BINOP},
> +};
> +
> +static const struct t_op mop2[] = {
> + {"G", FILGID, UNOP},
> + {"L", FILSYM, UNOP},
> + {"O", FILUID, UNOP},
> + {"S", FILSOCK,UNOP},
> + {"a", BAND, BBINOP},
> + {"b", FILBDEV,UNOP},
> + {"c", FILCDEV,UNOP},
> + {"d", FILDIR, UNOP},
> + {"e", FILEXIST,UNOP},
> + {"f", FILREG, UNOP},
> + {"g", FILSGID,UNOP},
> + {"h", FILSYM, UNOP}, /* for backwards compat */
> + {"k", FILSTCK,UNOP},
> + {"n", STRNZ, UNOP},
> + {"o", BOR, BBINOP},
> + {"p", FILFIFO,UNOP},
> + {"r", FILRD, UNOP},
> + {"s", FILGZ, UNOP},
> + {"t", FILTT, UNOP},
> + {"u", FILSUID,UNOP},
> + {"w", FILWR, UNOP},
> + {"x", FILEX, UNOP},
> + {"z", STREZ, UNOP},
> };
>
> static char **t_wp;
> @@ -390,26 +400,68 @@
> }
> }
>
> +#define VTOC(x) (const unsigned char *)((const
> struct t_op *)x)->op_text
> +
> +static int
> +compare1(const void *va, const void *vb)
> +{
> + const unsigned char *a = va;
> + const unsigned char *b = VTOC(vb);
> +
>
=== message truncated ===
____________________________________________________________________________________
Food fight? Enjoy some healthy debate
in the Yahoo! Answers Food & Drink Q&A.
http://answers.yahoo.com/dir/?link=list&sid=396545367