summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCojocaru Alexandru <xojoc@gmx.com>2013-04-28 03:03:45 +0100
committerPádraig Brady <P@draigBrady.com>2013-04-29 17:54:39 +0100
commitef9db5735a401f60eb5b4a18a365bf1ece525053 (patch)
tree836c6d92830d2fa3037e2378e4277dc634bb81ef
parent3e466ad05181d95057e6612ff11059c91396cd0e (diff)
downloadcoreutils-ef9db5735a401f60eb5b4a18a365bf1ece525053.tar.xz
cut: reduce CPU overhead in determining item to output
print_kth() is the central function of cut used to determine if an item is to be output or not, so simplify it by moving some logic outside. Benchmark results for this change are: $ yes abcdfeg | head -n1MB > big-file $ for c in orig split; do src/cut-$c 2>/dev/null echo -ne "\n== $c ==" time src/cut-$c -b1,3 big-file > /dev/null done == orig == real 0m0.111s user 0m0.108s sys 0m0.002s == split == real 0m0.088s user 0m0.081s sys 0m0.007s * src/cut.c (print_kth): Refactor a branch to outside the function. Related to http://bugs.gnu.org/13127
-rw-r--r--src/cut.c54
-rwxr-xr-xtests/misc/cut-huge-range.sh2
2 files changed, 27 insertions, 29 deletions
diff --git a/src/cut.c b/src/cut.c
index 8738c46a0..37615a34a 100644
--- a/src/cut.c
+++ b/src/cut.c
@@ -233,6 +233,20 @@ With no FILE, or when FILE is -, read standard input.\n\
exit (status);
}
+/* Return nonzero if the K'th field or byte is printable. */
+
+static bool
+print_kth (size_t k)
+{
+ bool k_selected = false;
+ if (0 < eol_range_start && eol_range_start <= k)
+ k_selected = true;
+ else if (current_rp->lo <= k && k <= current_rp->hi)
+ k_selected = true;
+
+ return k_selected ^ complement;
+}
+
/* Return nonzero if K'th byte is the beginning of a range. */
static inline bool
@@ -248,24 +262,6 @@ is_range_start_index (size_t k)
return is_start;
}
-/* Return nonzero if the K'th field or byte is printable. */
-
-static bool
-print_kth (size_t k, bool *range_start)
-{
- bool k_selected = false;
- if (0 < eol_range_start && eol_range_start <= k)
- k_selected = true;
- else if (current_rp->lo <= k && k <= current_rp->hi)
- k_selected = true;
-
- bool is_selected = k_selected ^ complement;
- if (range_start && is_selected)
- *range_start = is_range_start_index (k);
-
- return k_selected ^ complement;
-}
-
/* Comparison function for qsort to order the list of
struct range_pairs. */
static int
@@ -491,16 +487,18 @@ cut_bytes (FILE *stream)
else
{
next_item (&byte_idx);
- bool range_start;
- bool *rs = output_delimiter_specified ? &range_start : NULL;
- if (print_kth (byte_idx, rs))
+ if (print_kth (byte_idx))
{
- if (rs && *rs && print_delimiter)
+ if (output_delimiter_specified)
{
- fwrite (output_delimiter_string, sizeof (char),
- output_delimiter_length, stdout);
+ if (print_delimiter && is_range_start_index (byte_idx))
+ {
+ fwrite (output_delimiter_string, sizeof (char),
+ output_delimiter_length, stdout);
+ }
+ print_delimiter = true;
}
- print_delimiter = true;
+
putchar (c);
}
}
@@ -532,7 +530,7 @@ cut_fields (FILE *stream)
and the first field has been selected, or if non-delimited lines
must be suppressed and the first field has *not* been selected.
That is because a non-delimited line has exactly one field. */
- buffer_first_field = (suppress_non_delimited ^ !print_kth (1, NULL));
+ buffer_first_field = (suppress_non_delimited ^ !print_kth (1));
while (1)
{
@@ -578,7 +576,7 @@ cut_fields (FILE *stream)
}
continue;
}
- if (print_kth (1, NULL))
+ if (print_kth (1))
{
/* Print the field, but not the trailing delimiter. */
fwrite (field_1_buffer, sizeof (char), n_bytes - 1, stdout);
@@ -589,7 +587,7 @@ cut_fields (FILE *stream)
int prev_c = c;
- if (print_kth (field_idx, NULL))
+ if (print_kth (field_idx))
{
if (found_any_selected_field)
{
diff --git a/tests/misc/cut-huge-range.sh b/tests/misc/cut-huge-range.sh
index 8783e96ad..887197ae9 100755
--- a/tests/misc/cut-huge-range.sh
+++ b/tests/misc/cut-huge-range.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Ensure that cut does not allocate mem for a range like -b9999999999999-
+# Ensure that cut does not allocate mem for large ranges
# Copyright (C) 2012-2013 Free Software Foundation, Inc.