mirror of
git://git.sv.gnu.org/nano.git
synced 2024-12-27 20:59:45 +03:00
tweaks: elide a call of strlen() for every row
For a normal file (without overlong lines) the strlen() wasn't much
of a problem. But when there are very long lines, it wasted time
counting stuff that wouldn't be displayed on the current row anyway,
and reserved *far* too much memory for the displayable string.
Problem existed since commit cf0eed6c
from five years ago that traded
a continuous comparison (of the used space with the reserved space)
against a one-time big reservation up front involving a strlen().
In retrospect that was not a good trade-off when softwrapping.
The extra check (charwidth == 0) is incurred only by characters that
have their high bit set, so the average file (with only ASCII) is not
affected by this -- it just loses an unneeded call of strlen().
This commit is contained in:
parent
debb288115
commit
31a6931be9
18
src/winio.c
18
src/winio.c
@ -1717,8 +1717,12 @@ char *display_string(const char *text, size_t column, size_t span,
|
||||
/* The index of the first character that the caller wishes to show. */
|
||||
size_t start_col = wideness(text, start_index);
|
||||
/* The actual column where that first character starts. */
|
||||
char *converted;
|
||||
/* The expanded string we will return. */
|
||||
size_t stowaways = 20;
|
||||
/* The number of zero-width characters for which to reserve space. */
|
||||
size_t allocsize = (COLS + stowaways) * MAXCHARLEN + 1;
|
||||
/* The amount of memory to reserve for the displayable string. */
|
||||
char *converted = nmalloc(allocsize);
|
||||
/* The displayable string we will return. */
|
||||
size_t index = 0;
|
||||
/* Current position in converted. */
|
||||
size_t beyond = column + span;
|
||||
@ -1726,9 +1730,6 @@ char *display_string(const char *text, size_t column, size_t span,
|
||||
|
||||
text += start_index;
|
||||
|
||||
/* Allocate enough space for converting the relevant part of the line. */
|
||||
converted = nmalloc(strlen(text) * (MAXCHARLEN + tabsize) + 1);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (span > HIGHEST_POSITIVE) {
|
||||
statusline(ALERT, "Span has underflowed -- please report a bug");
|
||||
@ -1842,6 +1843,13 @@ char *display_string(const char *text, size_t column, size_t span,
|
||||
/* Determine whether the character takes zero, one, or two columns. */
|
||||
charwidth = wcwidth(wc);
|
||||
|
||||
/* Watch the number of zero-widths, to keep ample memory reserved. */
|
||||
if (charwidth == 0 && --stowaways == 0) {
|
||||
stowaways = 40;
|
||||
allocsize += stowaways * MAXCHARLEN;
|
||||
converted = nrealloc(converted, allocsize);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
/* On a Linux console, skip zero-width characters, as it would show
|
||||
* them WITH a width, thus messing up the display. See bug #52954. */
|
||||
|
Loading…
Reference in New Issue
Block a user