bobl@aeolus.UUCP (Bob Lewis) (04/26/85)
I just came across some rather interesting behavior in stdio that I think deserves greater dissemination. It isn't a bug, but it something that people should be aware of. Whenever you have a line-buffered output file, that means that stdio flushes the buffer whenever (a) the buffer overflows or (b) you output a newline. The interesting behavior is in the putc(3S) macro in /usr/include/stdio.h and in the function _flsbuf() that it calls. With line buffering, _flsbuf always resets the file's i/o buffer structure in such a way that putc will call _flsbuf for every output character sent to it so that _flsbuf can flush the buffer if that character is a newline. This means that every time you use putc, it costs a function call. In particular, note that standard out defaults to line buffering if it's a tty. One easy workaround is to disable line buffering. You can do this by installing your own buffer via setbuffer(3S), as shown in the program below. Interestingly, (in 4.2bsd at least) there is a function setlinebuf(3S) to enable line buffering, but none to turn it off explicitly. A procedure call per character is not trivial. The program below spends about 10% of its (VAX 780, 4.2bsd) time in _flsbuf when compiled without "-DFASTER". Terminal I/O-bound programs should behave similarly. - Bob Lewis ...!tektronix!teklds!bobl ----------------------- cut here ---------------------------- #include <stdio.h> main() { char buf[64]; char outbuf[1024]; int i, j; #ifdef FASTER setbuffer(stdout, outbuf, sizeof(outbuf)); #endif for (j = 0; j < 64; j++) { for (i = 0; i < 63; i++) buf[i] = 'a' + (random() % 26); buf[63] = '\n'; fwrite(buf, 1, 64, stdout); #ifdef FASTER fflush(stdout); /* be fair and do our own line flushing */ #endif } exit(0); }
chris@umcp-cs.UUCP (Chris Torek) (04/29/85)
4.3 has a much larger and grottier putc macro that avoids calling _flsbuf when an output file is unbuffered. However, I still favor using setbuf (not setlinebuf) and calling fflush whenever appropriate. By the way, in 4.3 stderr is also line buffered. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251) UUCP: {seismo,allegra,brl-bmd}!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland