Is Unix stdio slow?

Edward Wang edward at ucbarpa.Berkeley.EDU
Tue Oct 4 08:58:13 AEST 1988


Chris Torek writes:
>What about putchar?  It is even worse:
>
>	| putchar(C(fp))
>		sub	$1,stdout_cnt	| --cnt >= 0 ?
>		jls	flush
>		mov	stdout_ptr,r0	| *p = c,
>		mov	C(fp), at r0
>		tstbit	$7,stdout_flg	| flag&IS_LINE_BUFFERED
>		jz	no_nl_flush
>		cmp	@r0,$10		| && *p == '\n' ?
>		jne	no_nl_flush
>		push	$10		|	_flsbuf(stdout, '\n')
>		jmp	fls0		| (merge)
>	no_nl_flush:
> . . .

I should point out that this is not 4.3 putc().
The real 4.3 putc looks like this

#define putc(x, p)	(--(p)->_cnt >= 0 ?\
	(int)(*(unsigned char *)(p)->_ptr++ = (x)) :\
	(((p)->_flag & _IOLBF) && -(p)->_cnt < (p)->_bufsiz ?\
		((*(p)->_ptr = (x)) != '\n' ?\
			(int)(*(unsigned char *)(p)->_ptr++) :\
			_flsbuf(*(unsigned char *)(p)->_ptr, p)) :\
		_flsbuf((unsigned char)(x), p)))

The block buffered path is the second line and does not
check the _IOLBF bit.  It is, in fact, exactly as fast
as the old putc.  Of course this doesn't mean the C compiler
generates good code for it.


Peter da Silva writes:
>It always depresses me when I think that people are still doing line
>buffered output. The problem of handling stdout and stdin is a solved
>problem: do a flushbuf on all interactive streams whenever you do a
>fillbuf on any interactive stream. . .

The reason for implicit line buffering is to make certain programs
more responsive when writing to a tty while still run at full speed
when output is redirected.  These are not necessarily interactive
programs.  For example, "last -10 foo" isn't interactive (the flsbuf
when filbuf fix won't work on it), but you do want it to give you
output line-by-line in case foo logs in only infrequently.

I will go as far as to say that standard output to pipes should be
line buffered, since we no longer put pipes in files.



More information about the Comp.unix.wizards mailing list