After this question , a doubt comes up:
Once fopen() is faster than open() (for sequential writing/ready operations at least), the former is a library and the latter is a system call, what system call does fopen() do in a POSIX compilant OS?
CodePudding user response:
It calls open
.
fopen
itself is not faster than open
; it can't be, it's open
plus some extra work. The performance benefit, described in the linked question, is from the "buffering" done by the FILE
object over its entire lifecycle. The actual optimization is to call the write
primitive fewer times, providing more data each time.
Here is a simple way to demonstrate the effect: Compile this program.
#define _XOPEN_SOURCE 700
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
if (argc != 3) return 1;
long count = atol(argv[1]);
long chunk = atol(argv[2]);
if (count < 1 || chunk < 0) return 1;
FILE *sink = fopen("/dev/null", "wb");
if (!sink) return 1;
if (chunk) {
char *buf = malloc(chunk);
if (!buf) return 1;
if (setvbuf(sink, buf, _IOFBF, chunk)) return 1;
} else {
if (setvbuf(sink, 0, _IONBF, 0)) return 1;
}
while (count--) putc_unlocked('.', sink);
return 0;
}
It takes two arguments: the total number of bytes to write, and the size of the output buffer, in that order. Run it with various values of both parameters and time its performance; you should see that, e.g.
./a.out $((1024*1024*128)) 1
is much slower than
./a.out $((1024*1024*128)) 8192
The first number will need to be quite large for the difference to be measurable. Once you've played around with that for a while, run
strace ./a.out 50 1
and
strace ./a.out 50 50
to understand the difference in what's going on at the system call level. (If you are using an OS other than Linux, replace strace
with whatever the equivalent command is for that OS.)