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,stdoutunbuffered 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
catutility uses faster apis 6 times faster execution times.
as conclusion: not set stdin , stdout unbuffered, impact performance moderately large files.
Comments
Post a Comment