http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56981
--- Comment #4 from Janne Blomqvist <jb at gcc dot gnu.org> 2013-04-17 10:50:07 UTC --- The reason why gfortran is slow here is that for non-regular files we use unbuffered I/O. If you write to a regular file instead of /dev/null, you'll see us doing ~8 KB writes at a time. On my system, timing writing to /dev/null gives real 0m0.727s user 0m0.272s sys 0m0.452s whereas writing to a file gives real 0m0.202s user 0m0.180s sys 0m0.020s The reason for this is that non-regular files (a.k.a. special files) are special in many ways wrt seeking. Some allow seeking just fine, some always return 0, some return an error (and which special files behave in which way is to some extent different on different OS'es). As the buffered IO keeps track of the logical file pointer position, it can easily get out of sync with the physical position if it doesn't behave as for a regular file. Also, for special files users often expect non-buffered IO, e.g. they want output on the terminal directly instead of waiting until the 8 KB buffer fills up, programs communicating via pipes can deadlock if data sits in the buffers, etc. One could of course make "unbuffered" I/O in gfortran really mean "flush the buffer at the end of each I/O statement" rather than not using a buffer at all and instead using the raw POSIX I/O syscalls. This would perhaps not be a bad idea per se, but would require making the buffered I/O code handle special files in some sensible way. Another reason for gfortran slowness is that we do quite a lot of checking in data_transfer_init(), which means that there's quite a lot of per-record overhead. Writing a single element unformatted is thus the worst case. One way to speed up data_transfer_init, I think, is that instead of checking each flag bit (which says which I/O specifiers are present) separately, create a variable with forbidden flags for each I/O type (unformatted/formatted, sequential/direct/stream => 6x), and check the entire flag variable once (flag & forbidden_flags == 0). Only if there is an error, do the bit-by-bit checking in order to generate the error message.