1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 13:07:46 +00:00

LibJS: Speed up IndexedPropertyIterator by computing non-empty indices

This provides a huge speed-up for objects with large numbers as property
keys in some situation. Previously we would simply iterate from 0-<max>
and check if there's a non-empty value at each index - now we're being
smarter and compute a list of non-empty indices upfront, by checking
each value in the packed elements vector and appending the sparse
elements hashmap keys (for GenericIndexedPropertyStorage).

Consider this example, an object with a single own property, which is a
number increasing by a factor of 10 each iteration:

    for (let i = 0; i < 10; ++i) {
        const o = {[10 ** i]: "foo"};
        const start = Date.now();
        Object.getOwnPropertyNames(o);  // <-- IndexedPropertyIterator
        const end = Date.now();
        console.log(`${10 ** i} -> ${(end - start) / 1000}s`);
    }

Before this change:

    1 -> 0.0000s
    10 -> 0.0000s
    100 -> 0.0000s
    1000 -> 0.0000s
    10000 -> 0.0005s
    100000 -> 0.0039s
    1000000 -> 0.0295s
    10000000 -> 0.2489s
    100000000 -> 2.4758s
    1000000000 -> 25.5669s

After this change:

    1 -> 0.0000s
    10 -> 0.0000s
    100 -> 0.0000s
    1000 -> 0.0000s
    10000 -> 0.0000s
    100000 -> 0.0000s
    1000000 -> 0.0000s
    10000000 -> 0.0000s
    100000000 -> 0.0000s
    1000000000 -> 0.0000s

Fixes #3805.
This commit is contained in:
Linus Groh 2020-10-20 00:24:53 +01:00 committed by Andreas Kling
parent 0e900ca5df
commit a82c56f9f7
2 changed files with 50 additions and 10 deletions

View file

@ -130,6 +130,8 @@ public:
ValueAndAttributes value_and_attributes(Object* this_object, bool evaluate_accessors = true);
private:
void skip_empty_indices();
const IndexedProperties& m_indexed_properties;
u32 m_index;
bool m_skip_empty;
@ -164,6 +166,8 @@ public:
size_t array_like_size() const { return m_storage->array_like_size(); }
void set_array_like_size(size_t);
Vector<u32> indices() const;
Vector<ValueAndAttributes> values_unordered() const;
private: