From 4d6a2ba2a0f8646f0c44034ccf2e21167ab87b0f Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Fri, 2 Jun 2023 02:12:00 +0200 Subject: [PATCH] Reduce cost of resetting row attributes --- src/buffer/out/Row.cpp | 4 +++- src/inc/til/rle.h | 5 +++++ src/inc/til/small_vector.h | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/buffer/out/Row.cpp b/src/buffer/out/Row.cpp index 9d883b09502..a765e474b75 100644 --- a/src/buffer/out/Row.cpp +++ b/src/buffer/out/Row.cpp @@ -128,7 +128,9 @@ void ROW::Reset(const TextAttribute& attr) { _charsHeap.reset(); _chars = { _charsBuffer, _columnCount }; - _attr = { _columnCount, attr }; + // Constructing and then moving objects into place isn't free. + // Modifying the existing object is _much_ faster. + *_attr.runs().unsafe_shrink_to_size(1) = til::rle_pair{ attr, _columnCount }; _lineRendition = LineRendition::SingleWidth; _wrapForced = false; _doubleBytePadded = false; diff --git a/src/inc/til/rle.h b/src/inc/til/rle.h index fa9e3793678..d94c3a744e6 100644 --- a/src/inc/til/rle.h +++ b/src/inc/til/rle.h @@ -402,6 +402,11 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" return _runs; } + container& runs() noexcept + { + return _runs; + } + // Get the value at the position const_reference at(size_type position) const { diff --git a/src/inc/til/small_vector.h b/src/inc/til/small_vector.h index 4a1fe4eab90..6484b96da0f 100644 --- a/src/inc/til/small_vector.h +++ b/src/inc/til/small_vector.h @@ -622,6 +622,24 @@ namespace til _capacity = capacity; } + // This is a very unsafe shortcut to free the buffer and get a direct + // hold to the _buffer. The caller can then fill it with `size` items. + [[nodiscard]] T* unsafe_shrink_to_size(size_t size) noexcept + { + assert(size <= N); + + if (_capacity != N) + { + _deallocate(_data); + } + + _data = &_buffer[0]; + _capacity = N; + _size = size; + + return &_buffer[0]; + } + void push_back(const T& value) { emplace_back(value);