Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > cat

Reply
 
 
Jag
Guest
Posts: n/a
 
      03-06-2008
I've read parts of K&R's ANSI C v2 and this is what their cat looked
like but when I compared the speed of this code to gnu cat, it seems
very slow. How do I optimize this for greater speeds? is there an
alternative algorithm?

void catfile(FILE *in, FILE *out) {
register int num_char;

/*Get characters*/
while ((num_char = getc(in)) != EOF) {
/*Print to standard output*/
putc(num_char, out);
}
}

Thanks.
 
Reply With Quote
 
 
 
 
CBFalconer
Guest
Posts: n/a
 
      03-06-2008
Jag wrote:
>
> I've read parts of K&R's ANSI C v2 and this is what their cat
> looked like but when I compared the speed of this code to gnu
> cat, it seems very slow. How do I optimize this for greater
> speeds? is there an alternative algorithm?
>
> void catfile(FILE *in, FILE *out) {
> register int num_char;
>
> /*Get characters*/
> while ((num_char = getc(in)) != EOF) {
> /*Print to standard output*/
> putc(num_char, out);
> }
> }


You may find the following faster:

void catfile(FILE *in, FILE *out) {
int ch;

while (EOF != (ch = getc(in))) putc(out, ch);
}

If so, consider why.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.



--
Posted via a free Usenet account from http://www.teranews.com

 
Reply With Quote
 
 
 
 
Micah Cowan
Guest
Posts: n/a
 
      03-06-2008
Jag <(E-Mail Removed)> writes:

> I've read parts of K&R's ANSI C v2 and this is what their cat looked
> like but when I compared the speed of this code to gnu cat, it seems
> very slow. How do I optimize this for greater speeds? is there an
> alternative algorithm?
>
> void catfile(FILE *in, FILE *out) {
> register int num_char;
>
> /*Get characters*/
> while ((num_char = getc(in)) != EOF) {
> /*Print to standard output*/
> putc(num_char, out);
> }
> }


This example was intended to be just that: an example. It gives a
clear, concise method for copying in to out.

If you look at GNU cat's source code, you'll see that it's nowhere
near as clear and concise (this is due in no small part to the fact
that it has to do a good deal more than the above example does,
including some options that require a bit of processing on the input).

POSIX systems that support the thread-safety option have to lock the
I/O streams every time you call getc() or putc(). On such systems,
getc_unlocked() and putc_unlocked() (POSIX options, not Standard C)
will usually be notably faster. Some implementations also provide
other means for using the "unlocked" versions.

Other common techniques would be to read in larger blocks at a time,
or perhaps to avoid the Standard C buffered I/O calls and use POSIX
read(), write() (it's unclear to me how much better that is than to
use setvbuf() to turn off buffering and use fwrite() and fread(),
which is a good option if you'd like to stick to Standard C).

Taking a look at the source code for GNU cat and other similar
utilities like dd, for (Unix-specific) ideas on how to improve
efficiency.

--
HTH,
Micah J. Cowan
Programmer, musician, typesetting enthusiast, gamer...
http://micah.cowan.name/
 
Reply With Quote
 
Micah Cowan
Guest
Posts: n/a
 
      03-06-2008
CBFalconer <(E-Mail Removed)> writes:

> Jag wrote:
>>
>> I've read parts of K&R's ANSI C v2 and this is what their cat
>> looked like but when I compared the speed of this code to gnu
>> cat, it seems very slow. How do I optimize this for greater
>> speeds? is there an alternative algorithm?
>>
>> void catfile(FILE *in, FILE *out) {
>> register int num_char;
>>
>> /*Get characters*/
>> while ((num_char = getc(in)) != EOF) {
>> /*Print to standard output*/
>> putc(num_char, out);
>> }
>> }

>
> You may find the following faster:
>
> void catfile(FILE *in, FILE *out) {
> int ch;
>
> while (EOF != (ch = getc(in))) putc(out, ch);
> }
>
> If so, consider why.


I'm having a heck of a time figuring out why that should be any faster
(note that the order of your arguments for putc() are wrong).

The only differences I see are:
1. You changed some names
2. You elided the "register" keyword (which the compiler was free to
ignore anyway)
3. You put EOF first in the comparison
4. You elided some braces and a comment.

--
Micah J. Cowan
Programmer, musician, typesetting enthusiast, gamer...
http://micah.cowan.name/
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      03-06-2008
CBFalconer wrote:
> Jag wrote:
>> I've read parts of K&R's ANSI C v2 and this is what their cat
>> looked like but when I compared the speed of this code to gnu
>> cat, it seems very slow. How do I optimize this for greater
>> speeds? is there an alternative algorithm?
>>
>> void catfile(FILE *in, FILE *out) {
>> register int num_char;
>>
>> /*Get characters*/
>> while ((num_char = getc(in)) != EOF) {
>> /*Print to standard output*/
>> putc(num_char, out);
>> }
>> }

>
> You may find the following faster:
>
> void catfile(FILE *in, FILE *out) {
> int ch;
>
> while (EOF != (ch = getc(in))) putc(out, ch);
> }
>
> If so, consider why.


I don't see why it would be faster. As far as I can
tell, the only substantive change is the removal of
`register', which is unlikely to make a difference --
and if it does make a difference, it's likely to make
the revised code slower, not faster.

(Well, there's one other "speed improvement," and it
could be a large one: Code that doesn't compile uses very
little execution time! Have another look at the putc()
call ...)

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)lid
 
Reply With Quote
 
Richard
Guest
Posts: n/a
 
      03-06-2008
Micah Cowan <(E-Mail Removed)> writes:

> CBFalconer <(E-Mail Removed)> writes:
>
>> Jag wrote:
>>>
>>> I've read parts of K&R's ANSI C v2 and this is what their cat
>>> looked like but when I compared the speed of this code to gnu
>>> cat, it seems very slow. How do I optimize this for greater
>>> speeds? is there an alternative algorithm?
>>>
>>> void catfile(FILE *in, FILE *out) {
>>> register int num_char;
>>>
>>> /*Get characters*/
>>> while ((num_char = getc(in)) != EOF) {
>>> /*Print to standard output*/
>>> putc(num_char, out);
>>> }
>>> }

>>
>> You may find the following faster:
>>
>> void catfile(FILE *in, FILE *out) {
>> int ch;
>>
>> while (EOF != (ch = getc(in))) putc(out, ch);
>> }
>>
>> If so, consider why.

>
> I'm having a heck of a time figuring out why that should be any faster
> (note that the order of your arguments for putc() are wrong).
>
> The only differences I see are:
> 1. You changed some names
> 2. You elided the "register" keyword (which the compiler was free to
> ignore anyway)
> 3. You put EOF first in the comparison
> 4. You elided some braces and a comment.


It is highly unlikely to be faster. It is though very ugly and unlikely
to pass any half decent code review due to its condition and statement
on one line which makes it nigh on impossible to set a watch point
and/or breakpoint on the putc line if you were trying to trace/debug the
program. Falconer's continual disregard for programming niceties for
teamwork is somewhat surprising considering his vocal insistence on 100%
standards compliance. Unless (and it wouldn't surprise me), he considers
the removal of register and chopping out of some white space as
improving the compilation time ....... And on that subject I often find
it pays dividends in the maintenance stakes to always bracket off the
body of conditions even if they are only one line e.g

,----
| while(c){
| c=do(c);
| }
`----




 
Reply With Quote
 
Gerry Ford
Guest
Posts: n/a
 
      03-06-2008
Ohimigod!

I am recently given to understand that cat means something other than
one-half of the dead felines in arbitrary buckets.

I sense that you drank of the forbidden K&R chapter, forbidden, not by these
jerks but by the standard, Dan Pop, Elvis, and me.

--
Gerry Ford

"Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
beziehend.
"Eric Sosman" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed). ..
> CBFalconer wrote:
>> Jag wrote:
>>> I've read parts of K&R's ANSI C v2 and this is what their cat
>>> looked like but when I compared the speed of this code to gnu
>>> cat, it seems very slow. How do I optimize this for greater
>>> speeds? is there an alternative algorithm?
>>>
>>> void catfile(FILE *in, FILE *out) {
>>> register int num_char;
>>>
>>> /*Get characters*/
>>> while ((num_char = getc(in)) != EOF) {
>>> /*Print to standard output*/
>>> putc(num_char, out);
>>> }
>>> }

>>
>> You may find the following faster:
>>
>> void catfile(FILE *in, FILE *out) {
>> int ch;
>>
>> while (EOF != (ch = getc(in))) putc(out, ch);
>> }
>>
>> If so, consider why.

>
> I don't see why it would be faster. As far as I can
> tell, the only substantive change is the removal of
> `register', which is unlikely to make a difference --
> and if it does make a difference, it's likely to make
> the revised code slower, not faster.
>
> (Well, there's one other "speed improvement," and it
> could be a large one: Code that doesn't compile uses very
> little execution time! Have another look at the putc()
> call ...)
>
> --
> Eric Sosman
> (E-Mail Removed)lid



 
Reply With Quote
 
Micah Cowan
Guest
Posts: n/a
 
      03-06-2008
Richard <(E-Mail Removed)> writes:

> And on that subject I often find
> it pays dividends in the maintenance stakes to always bracket off the
> body of conditions even if they are only one line e.g
>
> ,----
> | while(c){
> | c=do(c);
> | }
> `----


You state that it pays dividends, but neglect to state how/why.

I'm guessing you mean that, if you have:

while(c)
c=do(c);

And then later want to add another statement in the while's body, then
you have to go through the tedium of adding braces first.

If that's what you mean, then my answer is:
- It's not appreciably harder to add braces later than it is to put
them in in the first place.
- In a decent editor, such as emacs or vim, it's simple to define a
new macro to automatically add (or remove) braces for one-line
bodies.

--
Micah J. Cowan
Programmer, musician, typesetting enthusiast, gamer...
http://micah.cowan.name/
 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      03-06-2008
Micah Cowan said:

<snip>

> I'm guessing you mean that, if you have:
>
> while(c)
> c=do(c);
>
> And then later want to add another statement in the while's body, then
> you have to go through the tedium of adding braces first.


That isn't the issue. If the compound statement has two statements, you
need the braces anyway, and it doesn't make a lot of odds whether you add
them now or later. In fact, if that *were* the only issue, deferring them
could save you (a miniscule amount of) work.

> If that's what you mean, then my answer is:
> - It's not appreciably harder to add braces later than it is to put
> them in in the first place.


Agreed. BUT - it is appreciably harder to remember to add them later on
special occasions than to put them in every time as a matter of habit.

> - In a decent editor, such as emacs or vim, it's simple to define a
> new macro to automatically add (or remove) braces for one-line
> bodies.


That's as maybe, but it isn't the work of adding such tools - it's the work
of remembering to use them. Unless, of course, by "automatic" you really
do mean automatic!!

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
Nick Keighley
Guest
Posts: n/a
 
      03-06-2008
On 6 Mar, 04:40, Micah Cowan <(E-Mail Removed)> wrote:
> CBFalconer <(E-Mail Removed)> writes:
> > Jag wrote:


> >> I've read parts of K&R's ANSI C v2 and this is what their cat
> >> looked like but when I compared the speed of this code to gnu
> >> cat, it seems very slow. How do I optimize this for greater
> >> speeds? is there an alternative algorithm?

>
> >> void catfile(FILE *in, FILE *out) {
> >> * * register int num_char;

>
> >> * * /*Get characters*/
> >> * * while ((num_char = getc(in)) != EOF) {
> >> * * * * /*Print to standard output*/
> >> * * * * putc(num_char, out);
> >> * * }
> >> }

>
> > You may find the following faster:

>
> > void catfile(FILE *in, FILE *out) {
> > * *int ch;

>
> > * *while (EOF != (ch = getc(in))) putc(out, ch);
> > }

>
> > If so, consider why.

>
> I'm having a heck of a time figuring out why that should be any faster


AOL.
me too
is the removal of register?


> (note that the order of your arguments for putc() are wrong).
>
> The only differences I see are:
> * 1. You changed some names
> * 2. You elided the "register" keyword (which the compiler was free to
> * ignore anyway)
> * 3. You put EOF first in the comparison
> * 4. You elided some braces and a comment.




--
Nick Keighley



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
PVLAN setup with Cat 2948G & Cat 6000/6500 help swrightsls@gmail.com Cisco 0 03-31-2007 03:52 PM
GBIC moved from Cat 3508 --> Cat 6513 shows wrong media type Hoffa Cisco 14 09-21-2006 04:25 AM
Cat 5 vs Cat 6 =?Utf-8?B?Unlhbg==?= Wireless Networking 1 04-21-2006 04:18 AM
Cat 6500 to Cat 6500 and VLANs Gary Cisco 2 12-02-2005 06:57 AM



Advertisments