Skip to content

Commit

Permalink
Reduce cost of resetting row attributes (#15497)
Browse files Browse the repository at this point in the history
Performance of printing enwik8.txt at the following block sizes:
4KiB (printf): 54MB/s -> 54MB/s
128KiB (cat): 101MB/s -> 104MB/s

## Validation Steps Performed
This change is easily verifiable via review.
  • Loading branch information
lhecker committed Jun 15, 2023
1 parent f3e2890 commit b8f402f
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 3 deletions.
6 changes: 4 additions & 2 deletions src/buffer/out/Row.cpp
Expand Up @@ -123,11 +123,13 @@ LineRendition ROW::GetLineRendition() const noexcept
// - Attr - The default attribute (color) to fill
// Return Value:
// - <none>
void ROW::Reset(const TextAttribute& attr)
void ROW::Reset(const TextAttribute& attr) noexcept
{
_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;
Expand Down
2 changes: 1 addition & 1 deletion src/buffer/out/Row.hpp
Expand Up @@ -124,7 +124,7 @@ class ROW final
void SetLineRendition(const LineRendition lineRendition) noexcept;
LineRendition GetLineRendition() const noexcept;

void Reset(const TextAttribute& attr);
void Reset(const TextAttribute& attr) noexcept;
void TransferAttributes(const til::small_rle<TextAttribute, uint16_t, 1>& attr, til::CoordType newWidth);
void CopyFrom(const ROW& source);

Expand Down
5 changes: 5 additions & 0 deletions src/inc/til/rle.h
Expand Up @@ -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
{
Expand Down
18 changes: 18 additions & 0 deletions src/inc/til/small_vector.h
Expand Up @@ -606,6 +606,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);
Expand Down

0 comments on commit b8f402f

Please sign in to comment.