diff --git a/NEWS b/NEWS index 4ba02413c..d789f406f 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,8 @@ GNU coreutils NEWS -*- outline -*- ** Improvements + 'cut -c' is up to 10x faster in UTF-8 locales. + 'od' allocates half the memory when -v,--output-duplicates is specified. 'tail' ensures prompt output when inotify is not being used, and when diff --git a/src/cut.c b/src/cut.c index 59b213f39..248e19a14 100644 --- a/src/cut.c +++ b/src/cut.c @@ -907,6 +907,17 @@ cut_characters_mode (FILE *stream, bool byte_mode) while (true) { + /* Skip unselected line suffixes without decoding each character. */ + if (idx && field_selection_exhausted (idx)) + { + idx_t available = mbbuf_topup (&mbbuf); + char *p = mbbuf.buffer + mbbuf.offset; + char *end = search_bytes (p, line_delim, available); + mbbuf_advance (&mbbuf, end ? end - p : available); + if (!end && available) + continue; + } + mcel_t g = mbbuf_get_char (&mbbuf); if (g.ch == line_delim) diff --git a/tests/cut/cut.pl b/tests/cut/cut.pl index c0c962ea0..da4dd0740 100755 --- a/tests/cut/cut.pl +++ b/tests/cut/cut.pl @@ -307,6 +307,10 @@ if ($mb_locale ne 'C') {ENV => "LC_ALL=$mb_locale"}], ['mb-char-5', '-c1-2', {IN=>"\xc3x\n"}, {OUT=>"\xc3x\n"}, {ENV => "LC_ALL=$mb_locale"}], + # Skip unselected suffixes across input buffers and reset at line ends. + ['mb-char-suffix', '-c1', + {IN=>"\xc3\xa9" . ("\xff" x (2 * $IO_BUFSIZE)) . "\nbignored"}, + {OUT=>"\xc3\xa9\nb\n"}, {ENV => "LC_ALL=$mb_locale"}], # Note mb-byte-n-1 and mb-byte-n-4 differ from coreutils-i18n patch, # which outputs a character if any byte is selected. # I.e., the i18n patch may output more bytes that the requested range.