소스 검색

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.
davidot 3 년 전
부모
커밋
eac3c4c127
1개의 변경된 파일8개의 추가작업 그리고 3개의 파일을 삭제
  1. 8 3
      Userland/Libraries/LibJS/Runtime/IndexedProperties.cpp

+ 8 - 3
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;
 }