buffer - Should I set stdout and stdin to be unbuffered in C? -
because of stdin
, stdout
buffering printf
, scanf
, getchar
not executed. flush output buffer using fflush(stdout)
code can become unreadable because of that. if set stdin
, stdout
unbuffered using setbuf(stdin, null)
, setbuf(stdout, null)
make program perform better or worse?
making stdin
or stdout
unbuffered can make program perform worse if handles large quantities of input / output , files. i/o requests broken down system calls on byte byte basis.
note buffering not cause printf
, scanf
, getchar
not executed: printf
output final destination can delayed, input operation via scanf
or getchar
may occur without prompt.
note setting intput unbuffered may not effective terminal because terminal performs own buffering controlled via stty
or ioctl
.
most c libraries have hack causes stdout
flushed when reading stdin
requires getting data system, behavior not specified in c standard, libraries not implement it. safe add calls fflush(stdout);
before input operations, , after transitory messages such progress meters. purposes, best let c startup determine appropriate buffering strategy depending upon type of system handle associated stdin
, stdout
streams. common default line buffered devices , buffered size of bufsiz
files.
to idea of potential performance hit, compile naive ccat
program:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { int c, size; if (argc > 1) { if (!strcmp(argv[1], "bufsiz")) size = bufsiz; else size = strtol(argv[1], null, 0); if (size == 0) { /* make stdin , stdout unbuffered */ setvbuf(stdin, null, _ionbf, 0); setvbuf(stdout, null, _ionbf, 0); } else if (size > 0) { /* make stdin , stdout buffered */ setvbuf(stdin, null, _iofbf, size); setvbuf(stdout, null, _iofbf, size); } else { /* make stdin , stdout line buffered */ setvbuf(stdin, null, _iolbf, -size); setvbuf(stdout, null, _iolbf, -size); } } while ((c = getchar()) != eof) { putchar(c); } return 0; }
time program execution copying large file several times minimize file caching side effects.
on debian linux box these timings 3.8mb text file:
chqrlie@linux:~/dev/stackoverflow$ time wc w 396684 396684 3755392 w real 0m0.072s user 0m0.068s sys 0m0.000s chqrlie@linux:~/dev/stackoverflow$ time cat < w > ww real 0m0.008s user 0m0.000s sys 0m0.004s chqrlie@linux:~/dev/stackoverflow$ time ./ccat < w > ww real 0m0.060s user 0m0.056s sys 0m0.000s chqrlie@linux:~/dev/stackoverflow$ time ./ccat 0x100000 < w > ww real 0m0.060s user 0m0.058s sys 0m0.000s chqrlie@linux:~/dev/stackoverflow$ time ./ccat 0 < w > ww real 0m5.326s user 0m0.632s sys 0m4.684s chqrlie@linux:~/dev/stackoverflow$ time ./ccat -0x1000 < w > ww real 0m0.533s user 0m0.104s sys 0m0.428s
as can see:
- setting
stdin
,stdout
unbuffered causes program slow down factor of 100, - using line buffering slows down factor of 10 (because lines short, 9 10 bytes on average)
- using larger buffer not show improvement, timing difference not significant,
- the naive implementation quite fast, real
cat
utility uses faster apis 6 times faster execution times.
as conclusion: not set stdin
, stdout
unbuffered, impact performance moderately large files.
Comments
Post a Comment