cat: use larger buffer sizes to reduce read/write-syscall overhead

* src/cat.c (max): Remove definition.  Use MAX from system.h instead.
(compute_buffer_size): New function to compute the input and output
buffer sizes, which are now set at 8 times st_blksize with a maximum
of 32KiB. Previously the typical block sizes used were 1KiB for pipes
and 4KiB for files, and now will be 8KiB and 32KiB respectively.
(main): Use it.
This change can double throughput on modern systems.  For timings,
see http://article.gmane.org/gmane.comp.gnu.core-utils.bugs/16040
Suggestion from Tzvi Rotshtein.
This commit is contained in:
Jim Meyering
2009-03-06 10:27:43 +01:00
parent 8b638f994a
commit 02c3dc9de8
2 changed files with 11 additions and 8 deletions

1
THANKS
View File

@@ -553,6 +553,7 @@ Torbjorn Granlund tege@nada.kth.se
Torbjorn Lindgren tl@funcom.no
Torsten Landschoff torsten@pclab.ifg.uni-kiel.de
Tristan Miller psychonaut@nothingisreal.com
Tzvi Rotshtein tzvi.ro@gmail.com
Ulrich Drepper drepper@gnu.org
Ulrich Hermisson ulrich_hermisson@hotmail.com
Urs Thuermann urs@isnogud.escape.de

View File

@@ -1,5 +1,5 @@
/* cat -- concatenate files and print on the standard output.
Copyright (C) 88, 90, 91, 1995-2008 Free Software Foundation, Inc.
Copyright (C) 88, 90, 91, 1995-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -48,10 +48,6 @@
proper_name_utf8 ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \
proper_name ("Richard M. Stallman")
/* Undefine, to avoid warning about redefinition on some systems. */
#undef max
#define max(h,i) ((h) > (i) ? (h) : (i))
/* Name of input file. May be "-". */
static char const *infile;
@@ -82,6 +78,12 @@ static char *line_num_end = line_buf + LINE_COUNTER_BUF_LEN - 3;
/* Preserves the `cat' function's local `newlines' between invocations. */
static int newlines2 = 0;
static inline size_t
compute_buffer_size (struct stat st)
{
return MIN (8 * ST_BLKSIZE (st), 32 * 1024);
}
void
usage (int status)
{
@@ -640,7 +642,7 @@ main (int argc, char **argv)
if (fstat (STDOUT_FILENO, &stat_buf) < 0)
error (EXIT_FAILURE, errno, _("standard output"));
outsize = ST_BLKSIZE (stat_buf);
outsize = compute_buffer_size (stat_buf);
/* Input file can be output file for non-regular files.
fstat on pipes returns S_IFSOCK on some systems, S_IFIFO
on others, so the checking should not be done for those types,
@@ -704,7 +706,7 @@ main (int argc, char **argv)
ok = false;
goto contin;
}
insize = ST_BLKSIZE (stat_buf);
insize = compute_buffer_size (stat_buf);
/* Compare the device and i-node numbers of this input file with
the corresponding values of the (output file associated with)
@@ -726,7 +728,7 @@ main (int argc, char **argv)
if (! (number | show_ends | show_nonprinting
| show_tabs | squeeze_blank))
{
insize = max (insize, outsize);
insize = MAX (insize, outsize);
inbuf = xmalloc (insize + page_size - 1);
ok &= simple_cat (ptr_align (inbuf, page_size), insize);