Your hard disk has a cache
The operating system has a cache for the currently open files
Your standard C library also has a buffer for the currently open files
You can be pretty damn sure that each fgetc call does NOT result in your process going to sleep whilst it waits for a few mS for the disk to deliver the goods.
IMO, the only reason fgets will be faster is that it is only one function call vs. the many you make with fgetc. Both at some point both calls will get caught up waiting for the disk when the various internal buffers are empty, at which point the milliseconds to do this will swamp the microseconds of difference between making a few function calls.
And the time taken to read a char is likely to be small (either way) in comparison to the rest of the work your program has to perform.
Write the program, then start measuring the performance using a profiler. Bottlenecks are not always in the obvious places...
Or just test it
Code:
#include <stdio.h>
// copy using fread
void copy1 ( char *infile, char *outfile ) {
FILE *in = fopen( infile, "rb" );
FILE *out= fopen( outfile, "wb" );
char buff[BUFSIZ];
size_t n;
while ( (n=fread(buff,1,BUFSIZ,in)) != 0 ) {
fwrite( buff, 1, n, out );
}
fclose( in );
fclose( out );
}
// copy using fgets on each line
void copy2 ( char *infile, char *outfile ) {
FILE *in = fopen( infile, "rt" );
FILE *out= fopen( outfile, "wt" );
char buff[BUFSIZ];
while ( fgets( buff, BUFSIZ, in ) != NULL ) {
fputs( buff, out );
}
fclose( in );
fclose( out );
}
// copy using fgetc on each char
void copy3 ( char *infile, char *outfile ) {
FILE *in = fopen( infile, "rt" );
FILE *out= fopen( outfile, "wt" );
int ch;
while ( (ch=fgetc(in)) != EOF ) {
fputc( ch, out );
}
fclose( in );
fclose( out );
}
/*
* This macro found on
* http://www.c-for-dummies.com/compilers/djgpp_asm.html
*/
#define RDTSC(llptr) ({ \
__asm__ __volatile__ ( \
".byte 0x0f; .byte 0x31" \
: "=A" (llptr) \
: : "eax", "edx"); })
int main ( ) {
unsigned long long a, b;
RDTSC(a);
RDTSC(b);
printf( "Overhead: %lld -> %lld = %10lld\n", a, b, b-a );
RDTSC(a);
sleep(1);
RDTSC(b);
printf( "Sleep(1): %lld -> %lld = %10lld\n", a, b, b-a );
RDTSC(a);
copy1( "4a.txt", "5a.txt" );
RDTSC(b);
printf( "Copy1: %lld -> %lld = %10lld\n", a, b, b-a );
RDTSC(a);
copy2( "4b.txt", "5b.txt" );
RDTSC(b);
printf( "Copy2: %lld -> %lld = %10lld\n", a, b, b-a );
RDTSC(a);
copy3( "4c.txt", "5c.txt" );
RDTSC(b);
printf( "Copy3: %lld -> %lld = %10lld\n", a, b, b-a );
return 0;
}
I got these results
Overhead: 6286077368030 -> 6286077368103 = 73
Sleep(1): 6286077462890 -> 6286307919537 = 230456647
Copy1: 6286308653110 -> 6286315490382 = 6837272
Copy2: 6286315587619 -> 6286348807055 = 33219436
Copy3: 6286349278809 -> 6286386417099 = 37138290
On my machine, thats like .01 of a second slower to process a 1/2MB file, using fgetc instead of fgets. If you're really determined to do something, then just fread() the whole file into memory in one go.