LibJS: Avoid some heap allocations in JSRopeString::resolve()

- Give piece vectors some inline capacity (for the common case of a+b)
- Pre-calculate the sum of UTF-16 code unit lengths for StringBuilder
This commit is contained in:
Andreas Kling 2025-10-04 10:16:36 +02:00 committed by Andreas Kling
parent 51ea4a7e2a
commit 0c3f113e05

View File

@ -222,12 +222,13 @@ void RopeString::resolve(EncodingPreference preference) const
// This vector will hold all the pieces of the rope that need to be assembled
// into the resolved string.
Vector<PrimitiveString const*> pieces;
Vector<PrimitiveString const*, 2> pieces;
size_t approximate_length = 0;
size_t length_in_utf16_code_units = 0;
// NOTE: We traverse the rope tree without using recursion, since we'd run out of
// stack space quickly when handling a long sequence of unresolved concatenations.
Vector<PrimitiveString const*> stack;
Vector<PrimitiveString const*, 2> stack;
stack.append(m_rhs);
stack.append(m_lhs);
while (!stack.is_empty()) {
@ -241,13 +242,15 @@ void RopeString::resolve(EncodingPreference preference) const
if (current->has_utf8_string())
approximate_length += current->utf8_string_view().length();
if (preference == EncodingPreference::UTF16)
length_in_utf16_code_units += current->length_in_utf16_code_units();
pieces.append(current);
}
if (preference == EncodingPreference::UTF16) {
// The caller wants a UTF-16 string, so we can simply concatenate all the pieces
// into a UTF-16 code unit buffer and create a Utf16String from it.
StringBuilder builder(StringBuilder::Mode::UTF16);
StringBuilder builder(StringBuilder::Mode::UTF16, length_in_utf16_code_units);
for (auto const* current : pieces) {
if (current->has_utf16_string())