summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2024-11-30 12:27:11 +1100
committerMaxime Coste <mawww@kakoune.org>2024-11-30 23:29:34 +1100
commit8769b94eb25cd7402db6caa4f0d4b417f6365703 (patch)
tree06a4b5563c20e157292e31e2c6fe41f60c778a14 /src
parent7ae1fd683defbd11b54ba7046df69be692ce4de5 (diff)
Cache buffer lines ArrayView in BufferIterator
The extra indirection of going through the buffer can be costly as the compiler does not know the buffer is not supposed to be mutated during iteration, so it has to actually reload the values which adds memory accesses in the Buffer instance which can be costly in say regex searches where memory access tends to dominate performance. Storing this in the BufferIterator lets the compiler put this info in registers and not reload it.
Diffstat (limited to 'src')
-rw-r--r--src/buffer.hh2
-rw-r--r--src/buffer.inl.hh8
2 files changed, 6 insertions, 4 deletions
diff --git a/src/buffer.hh b/src/buffer.hh
index ec2b9620..fd748213 100644
--- a/src/buffer.hh
+++ b/src/buffer.hh
@@ -95,6 +95,7 @@ public:
private:
SafePtr<const Buffer> m_buffer;
+ ArrayView<const StringDataPtr> m_lines;
BufferCoord m_coord;
StringView m_line;
};
@@ -122,6 +123,7 @@ public:
ReadOnly = 1 << 6,
};
friend constexpr bool with_bit_ops(Meta::Type<Flags>) { return true; }
+ friend class BufferIterator;
enum class HistoryId : size_t { First = 0, Invalid = (size_t)-1 };
diff --git a/src/buffer.inl.hh b/src/buffer.inl.hh
index acaa699f..f3e46378 100644
--- a/src/buffer.inl.hh
+++ b/src/buffer.inl.hh
@@ -99,7 +99,7 @@ inline BufferCoord Buffer::end_coord() const
}
inline BufferIterator::BufferIterator(const Buffer& buffer, BufferCoord coord) noexcept
- : m_buffer{&buffer}, m_coord{coord},
+ : m_buffer{&buffer}, m_lines{buffer.m_lines}, m_coord{coord},
m_line{coord.line < buffer.line_count() ? (*m_buffer)[coord.line] : StringView{}} {}
inline bool BufferIterator::operator==(const BufferIterator& iterator) const noexcept
@@ -165,8 +165,8 @@ inline BufferIterator& BufferIterator::operator++()
{
if (++m_coord.column == m_line.length())
{
- m_line = (++m_coord.line < m_buffer->line_count()) ?
- (*m_buffer)[m_coord.line] : StringView{};
+ m_line = ((size_t)++m_coord.line < m_lines.size()) ?
+ m_lines[(size_t)m_coord.line]->strview() : StringView{};
m_coord.column = 0;
}
return *this;
@@ -176,7 +176,7 @@ inline BufferIterator& BufferIterator::operator--()
{
if (m_coord.column == 0)
{
- m_line = (*m_buffer)[--m_coord.line];
+ m_line = m_lines[(size_t)--m_coord.line]->strview();
m_coord.column = m_line.length() - 1;
}
else