From eac3c4c1276eaf95b532a8863f107cbfd22320dd Mon Sep 17 00:00:00 2001 From: davidot Date: Sat, 12 Feb 2022 23:44:58 +0100 Subject: [PATCH] LibJS: Use entire array of SimpleIndexedPropertyStorage before growing A common use case in JS is pushing items in an array in a loop. A simple test case of 100_000 pushes took around ~20 seconds. This is due to the fact that any pushed element per definition is beyond the current size of the array. This meant calling grow_storage_if_needed which then grew the storage by 25%. But this was done on every single push, growing the array just a little bigger than its current capacity. Now we now first use capacity of the array and only grow if the array is actually full. This decreases the time for 100_000 to around 0.35 seconds. One problem is that we never shrink the capacity of the array but this was already an issue before this. --- .../Libraries/LibJS/Runtime/IndexedProperties.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/IndexedProperties.cpp b/Userland/Libraries/LibJS/Runtime/IndexedProperties.cpp index bae17bbd2b..7d13f767b0 100644 --- a/Userland/Libraries/LibJS/Runtime/IndexedProperties.cpp +++ b/Userland/Libraries/LibJS/Runtime/IndexedProperties.cpp @@ -35,8 +35,13 @@ void SimpleIndexedPropertyStorage::grow_storage_if_needed() { if (m_array_size <= m_packed_elements.size()) return; - // Grow storage by 25% at a time. - m_packed_elements.resize(m_array_size + (m_array_size / 4)); + + if (m_array_size <= m_packed_elements.capacity()) { + m_packed_elements.resize_and_keep_capacity(m_array_size); + } else { + // When the array is actually full grow storage by 25% at a time. + m_packed_elements.resize_and_keep_capacity(m_array_size + (m_array_size / 4)); + } } void SimpleIndexedPropertyStorage::put(u32 index, Value value, PropertyAttributes attributes) @@ -73,7 +78,7 @@ ValueAndAttributes SimpleIndexedPropertyStorage::take_last() bool SimpleIndexedPropertyStorage::set_array_like_size(size_t new_size) { m_array_size = new_size; - m_packed_elements.resize(new_size); + m_packed_elements.resize_and_keep_capacity(new_size); return true; }