Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 (Tek) 9/28/84 based on 9/17/84; site aeolus.UUCP Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxt!houxm!vax135!cornell!uw-beaver!tektronix!teklds!aeolus!bobl From: bobl@aeolus.UUCP (Bob Lewis) Newsgroups: net.unix-wizards Subject: line buffering in stdio Message-ID: <25@aeolus.UUCP> Date: Fri, 26-Apr-85 16:44:26 EDT Article-I.D.: aeolus.25 Posted: Fri Apr 26 16:44:26 1985 Date-Received: Sun, 28-Apr-85 08:38:50 EDT Organization: Tektronix, Beaverton OR Lines: 56 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 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); }