From 02c3dc9de8d3cf26b319b7a7b144878a2afb91bb Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Fri, 6 Mar 2009 10:27:43 +0100 Subject: 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. --- src/cat.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/cat.c b/src/cat.c index 543e5cf13..04eb204d4 100644 --- a/src/cat.c +++ b/src/cat.c @@ -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); -- cgit v1.2.3-54-g00ecf