Speed up unicode_in_range

This commit is contained in:
Kovid Goyal 2024-10-26 13:52:00 +05:30
parent 7ff7947ab3
commit 9d4818e58b
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
4 changed files with 28 additions and 16 deletions

View file

@ -225,17 +225,6 @@ text_at(Line* self, Py_ssize_t xval) {
return cell_text(self->cpu_cells + xval, self->text_cache);
}
static size_t
cell_as_unicode(ListOfChars *lc, bool include_cc, Py_UCS4 *buf, char_type zero_char) {
size_t n = 1;
buf[0] = lc->chars[0] ? lc->chars[0] : zero_char;
if (include_cc && lc->count > 1) {
memcpy(buf + 1, lc->chars + 1, (lc->count - 1) * sizeof(lc->chars[0]));
n += lc->count - 1;
}
return n;
}
size_t
cell_as_unicode_for_fallback(const ListOfChars *lc, Py_UCS4 *buf) {
size_t n = 1;
@ -271,15 +260,16 @@ PyObject*
unicode_in_range(const Line *self, const index_type start, const index_type limit, const bool include_cc, const bool add_trailing_newline, const bool skip_zero_cells) {
size_t n = 0;
static Py_UCS4 buf[4096];
RAII_ListOfChars(lc);
ListOfChars lc;
char_type previous_width = 0;
for(index_type i = start; i < limit; i++) {
text_in_cell(self->cpu_cells + i, self->text_cache, &lc);
for (index_type i = start; i < limit; i++) {
lc.chars = buf + n; lc.capacity = arraysz(buf) - n;
if (!text_in_cell_without_alloc(self->cpu_cells + i, self->text_cache, &lc)) break;
if (!lc.chars[0]) {
if (previous_width == 2) { previous_width = 0; continue; };
if (skip_zero_cells) continue;
lc.chars[0] = ' ';
}
if (lc.count + n >= arraysz(buf)) break;
if (lc.chars[0] == '\t') {
buf[n++] = '\t';
unsigned num_cells_to_skip_for_tab = lc.count > 1 ? lc.chars[1] : 0;
@ -288,7 +278,7 @@ unicode_in_range(const Line *self, const index_type start, const index_type limi
num_cells_to_skip_for_tab--;
}
} else {
n += cell_as_unicode(&lc, include_cc, buf + n, ' ');
n += include_cc ? lc.count : 1;
}
previous_width = self->gpu_cells[i].attrs.width;
}

View file

@ -92,6 +92,14 @@ text_in_cell(const CPUCell *c, const TextCache *tc, ListOfChars *ans) {
}
}
static inline bool
text_in_cell_without_alloc(const CPUCell *c, const TextCache *tc, ListOfChars *ans) {
if (c->ch_is_idx) return tc_chars_at_index_without_alloc(tc, c->ch_or_idx, ans);
ans->count = 1;
ans->chars[0] = c->ch_or_idx;
return true;
}
static inline void
cell_set_chars(CPUCell *c, TextCache *tc, const ListOfChars *lc) {
if (lc->count <= 1) cell_set_char(c, lc->chars[0]);

View file

@ -87,6 +87,19 @@ tc_chars_at_index(const TextCache *self, char_type idx, ListOfChars *ans) {
}
}
bool
tc_chars_at_index_without_alloc(const TextCache *self, char_type idx, ListOfChars *ans) {
if (self->array.count > idx) {
ans->count = self->array.items[idx].count;
if (ans->capacity < ans->count) return false;
memcpy(ans->chars, self->array.items[idx].chars, sizeof(ans->chars[0]) * ans->count);
} else {
ans->count = 0;
}
return true;
}
unsigned
tc_num_codepoints(const TextCache *self, char_type idx) {
return self->array.count > idx ? self->array.items[idx].count : 0;

View file

@ -53,4 +53,5 @@ void tc_chars_at_index(const TextCache *self, char_type idx, ListOfChars *ans);
unsigned tc_chars_at_index_ansi(const TextCache *self, char_type idx, ANSIBuf *output);
char_type tc_get_or_insert_chars(TextCache *self, const ListOfChars *chars);
char_type tc_first_char_at_index(const TextCache *self, char_type idx);
bool tc_chars_at_index_without_alloc(const TextCache *self, char_type idx, ListOfChars *ans);
unsigned tc_num_codepoints(const TextCache *self, char_type idx);