Home > OS >  fopen vs open (in C) in POSIX
fopen vs open (in C) in POSIX

Time:10-15

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.)

  • Related