Why the fwrite libc function is faster than the syscall write function?
c, linux
Solution
Timing my application with an input of 10Mb in size and echoing it to /dev/null, and making sure the file in not cached, I've found that libc's frwite is faster by a LARGE scale when using very small buffers (1 byte in case).
`fwrite` works on streams, which are buffered. Therefore many small buffers will be faster because it won't run a costly system call until the buffer fills up (or you flush it or close the stream). On the other hand, small buffers being sent to `write` will run a costly system call for each buffer - that's where you're losing the speed. With a 1024 byte stream buffer, and writing 1 byte buffers, you're looking at 1024 `write` calls for each kilobyte, rather than 1024 `fwrite` calls turning into one `write` - see the difference?
For big buffers the difference will be small, because there will be less buffering, and therefore a more consistent number of system calls between `fwrite` and `write`.
In other words, `fwrite(3)` is just a library routine that collects up output into chunks, and then calls `write(2)`. Now, `write(2)`, is a system call which traps into the kernel. That's where the I/O actually happens. There is some overhead for simply calling into the kernel, and then there is the time it takes to actually write something. If you use large buffers, you will find that `write(2)` is faster because it eventually has to be called anyway, and if you are writing one or more times per fwrite then the fwrite buffering overhead is just that: more overhead.
If you want to read more about it, you can have a look at this document, which explains standard I/O streams.
Problem
After providing the same program which reads a random generated input file and echoes the same string it read to an output. The only difference is that on one side I'm providing the read and write methods from linux syscalls, and on the other side I'm using fread/fwrite. Timing my application with an input of 10Mb in size and echoing it to /dev/null, and making sure the file is not cached, I've found that libc's fwrite is faster by a LARGE scale when using very small buffers (1 byte in case). Here is my output from time, using fwrite: ``` real 0m0.948s user 0m0.780s sys 0m0.012s ``` And using the syscall write: ``` real 0m8.607s user 0m0.972s sys 0m7.624s ``` The only possibility that I can think of is that internally libc is already buffering my input... Unfortunately I couldn't find that much information around the web, so maybe the gurus here could help me out.