C style
Krzysztof Kozminski
kk at duke.UUCP
Sun Oct 6 09:08:31 AEST 1985
In article <2848 at sun.uucp> Guy Harris writes (quoting somebody else, but in
apparent support of this other person's critique of yet somebody else):
>> > For Heaven's sake, the big problem with this code is that the conditional
>> > is quite unreadable in in-line code like this. I'd prefer
>> > while (illegal (ch = getch()))
>> > (where "illegal" is defined as a function testing its character argument).
>> It may enhance readability, but it's not worthwhile. You've just managed
>> to add a context switch per *character*. Now, imagine what that's going to
>> do to a program like spell.
>Yes. The System V "fgrep" uses a subroutine to do character comparisons. The
>4.2BSD version uses a macro instead. The 4.2BSD version is substantially faster
Uh, aren't you exagerrating a little with all this speed optimization? How many
people use spell or fgrep on input that is hand-typed in real time? Wasn't it
*obvious* from the original article that the code was meant to deal with a live
human on the input end and *not* to read from a file? Just to remind, this was
something to the effect of:
while (illegal (ch = getch()))
make_noise_and_protest_loudly(); /* I.e., putchar(BELL) */
I wish I could type fast enough to see any performance degradation from the
function call overhead in this situation :-)
If I wanted to do a *really fast* I/O with checking if input characters are
legal or not, and unless the set of illegal characters had nice properties
(like <32 or having some particular bit set or something) I'd trade off space
for speed, and do:
#define fast_access char /* or int, depending on the addressability and
comaparison speed considerations */
#if EOF != -1
something to call the attention of whoever is going to port this to elsewhere
(portability problems with the "257" below could be resolved analogously).
#endif
fast_access illegal[257]; /* Initialized to evaluate TRUE for illegal and
FALSE for legal characters. */
#define ILLEGAL(a) ( illegal [1+(a)] ) /* Lots of comments why this */
while ( ILLEGAL(ch=getchar()) )
{ complain_in_some_way }
Fast, readable, no problems with side effects in macro substitution, either.
And you can change the illegal set dynamically.
Now if I *really* cared about speed ... I'd rewrite getchar, too, to avoid the
addition. Or experiment with:
#define ILLEGAL(a) ((illegal+1)[a]) /* Lots of comments what is this
expected to be */
which should avoid run-time addition. Or I'd write this in assembler. Or
perhaps design a custom processor :-)
More information about the Comp.lang.c
mailing list