[net.sources] benchmarks for different io copying routines

perlman@wanginst.UUCP (Gary Perlman) (01/22/85)

The following are basic input to output copy programs.
There is a shell script to test their speeds.
They show that there is about a 20:1 difference between
the fastest and the slowest.  The results are contained
here, but were originally posted to net.unix in response
to someone's question.

Gary Perlman/Wang Institute/Tyngsboro, MA/01879/(617) 649-9731

#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	fgetputc.c
#	freadwrite.c
#	getputc.c
#	readwrite.c
#	msg
#	bench
#	makefile
# This archive created: Mon Jan 21 22:08:15 1985
# By:	Gary Perlman (Wang Institute, Tyngsboro, MA 01879 USA)
export PATH; PATH=/bin:$PATH
echo shar: extracting "'fgetputc.c'" '(109 characters)'
if test -f 'fgetputc.c'
then
	echo shar: over-writing existing file "'fgetputc.c'"
fi
cat << \SHAR_EOF > 'fgetputc.c'
#include <stdio.h>

main ()
	{
	register	int 	C;
	while ((C = fgetc (stdin)) != EOF)
		fputc (C, stdout);
	}
SHAR_EOF
if test 109 -ne "`wc -c 'fgetputc.c'`"
then
	echo shar: error transmitting "'fgetputc.c'" '(should have been 109 characters)'
fi
echo shar: extracting "'freadwrite.c'" '(183 characters)'
if test -f 'freadwrite.c'
then
	echo shar: over-writing existing file "'freadwrite.c'"
fi
cat << \SHAR_EOF > 'freadwrite.c'
#include <stdio.h>

main ()
	{
	char	buf[BUFSIZ];
	register	int 	nbytes;
	while (nbytes = fread (buf, sizeof (*buf), BUFSIZ, stdin))
		fwrite (buf, sizeof (*buf), nbytes, stdout);
	}
SHAR_EOF
if test 183 -ne "`wc -c 'freadwrite.c'`"
then
	echo shar: error transmitting "'freadwrite.c'" '(should have been 183 characters)'
fi
echo shar: extracting "'getputc.c'" '(107 characters)'
if test -f 'getputc.c'
then
	echo shar: over-writing existing file "'getputc.c'"
fi
cat << \SHAR_EOF > 'getputc.c'
#include <stdio.h>

main ()
	{
	register	int 	C;
	while ((C = getc (stdin)) != EOF)
		putc (C, stdout);
	}
SHAR_EOF
if test 107 -ne "`wc -c 'getputc.c'`"
then
	echo shar: error transmitting "'getputc.c'" '(should have been 107 characters)'
fi
echo shar: extracting "'readwrite.c'" '(142 characters)'
if test -f 'readwrite.c'
then
	echo shar: over-writing existing file "'readwrite.c'"
fi
cat << \SHAR_EOF > 'readwrite.c'
#define	BUFSIZ	1024
main ()
	{
	char	buf[BUFSIZ];
	register	int 	nbytes;
	while (nbytes = read (0, buf, BUFSIZ))
		write (1, buf, nbytes);
	}
SHAR_EOF
if test 142 -ne "`wc -c 'readwrite.c'`"
then
	echo shar: error transmitting "'readwrite.c'" '(should have been 142 characters)'
fi
echo shar: extracting "'msg'" '(1104 characters)'
if test -f 'msg'
then
	echo shar: over-writing existing file "'msg'"
fi
cat << \SHAR_EOF > 'msg'
Which is faster, read/write or fread/fwrite?
There is no comparison.  Here are some times
for copying /etc/termcap (38123 chars).

SIZE NAME        COMMENT
6144 fgetputc    using fgetc and fputc with stdio
7168 freadwrite  using fread and fwrite BUFSIZ blocks with stdio
6144 getputc     using getc and putc (macros) with stdio
5120 readwrite   using read and write BUFSIZ blocks (no stdio)

The results:
PROGRAM       user   sys   total
fgetputc      2.1    0.2    2.3
freadwrite    1.1    0.1    1.2
getputc       0.7    0.1    0.8
readwrite     0.0    0.1    0.1


That is a huge effect!  A factor of 23.
Some observations:
	fgetc and fputc are functions which getc and putc are macros.
	The overhead of 38123 (times 2) function calls is immense.

	I think all the stdio functions are doing reads and writes.
	It looks like fread and fwrite are using more.

	I am not sure, but there may be some strange interactions
	if read and write are used directly in conjunction with stdio.

I am posting the benchmarking programs to net.sources.

Gary Perlman/Wang Institute/Tyngsboro, MA/01879/(617) 649-9731
SHAR_EOF
if test 1104 -ne "`wc -c 'msg'`"
then
	echo shar: error transmitting "'msg'" '(should have been 1104 characters)'
fi
echo shar: extracting "'bench'" '(71 characters)'
if test -f 'bench'
then
	echo shar: over-writing existing file "'bench'"
fi
cat << \SHAR_EOF > 'bench'
for prog
do
	echo -n $prog
	time $prog < /etc/termcap > /dev/null
done
SHAR_EOF
if test 71 -ne "`wc -c 'bench'`"
then
	echo shar: error transmitting "'bench'" '(should have been 71 characters)'
fi
chmod +x 'bench'
echo shar: extracting "'makefile'" '(431 characters)'
if test -f 'makefile'
then
	echo shar: over-writing existing file "'makefile'"
fi
cat << \SHAR_EOF > 'makefile'
test: progs
	bench fgetputc freadwrite getputc readwrite ireadwrite
progs: fgetputc freadwrite getputc readwrite ireadwrite
	make fgetputc freadwrite getputc readwrite ireadwrite
archive:
	shar -cv *.c msg bench makefile > iobench.sh
fgetputc:
	cc fgetputc.c -o fgetputc
freadwrite:
	cc freadwrite.c -o freadwrite
getputc:
	cc getputc.c -o getputc
readwrite:
	cc readwrite.c -o readwrite
ireadwrite:
	cc ireadwrite.c -o ireadwrite
SHAR_EOF
if test 431 -ne "`wc -c 'makefile'`"
then
	echo shar: error transmitting "'makefile'" '(should have been 431 characters)'
fi
#	End of shell archive
exit 0