From e8f4ae487d228dac491a446ed548400176331ae9 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Fri, 19 Jul 2024 15:46:14 -0400 Subject: [PATCH] LibJS: Pre-allocate the resolved rope string's underlying buffer For performance, rather than slowly incrementing the capacity of the rope string's buffer, compute an approximate length for that buffer to be reserved up front. --- Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp b/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp index d74abec01c1..b5417d59255 100644 --- a/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp +++ b/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp @@ -254,6 +254,7 @@ void PrimitiveString::resolve_rope_if_needed(EncodingPreference preference) cons // This vector will hold all the pieces of the rope that need to be assembled // into the resolved string. Vector pieces; + size_t approximate_length = 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. @@ -267,6 +268,9 @@ void PrimitiveString::resolve_rope_if_needed(EncodingPreference preference) cons stack.append(current->m_lhs); continue; } + + if (current->has_utf8_string()) + approximate_length += current->utf8_string_view().length(); pieces.append(current); } @@ -286,7 +290,7 @@ void PrimitiveString::resolve_rope_if_needed(EncodingPreference preference) cons } // Now that we have all the pieces, we can concatenate them using a StringBuilder. - StringBuilder builder; + StringBuilder builder(approximate_length); // We keep track of the previous piece in order to handle surrogate pairs spread across two pieces. PrimitiveString const* previous = nullptr;