Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: ECMAScript2023 & ECMAScript2022 array methods performance improvement for proxy #3792

Merged
merged 6 commits into from Nov 25, 2023

Conversation

tonyraoul
Copy link
Contributor

@tonyraoul tonyraoul commented Nov 11, 2023

Code change checklist

  • Added/updated unit tests
  • Updated /docs. For new functionality, at least API.md should be updated
  • Verified that there is no significant performance drop (yarn mobx test:performance)

Context

ECMAScript023 is introducing a new set of methods to the array object as specified here

These methods already works with mobx, however they need to be added as arrayExtension to prevent proxy performance penalty, most methods provides x2-x3 performance gain while others shows minimal performance gain.

Also I have noticed the at method from ECMAScript2022 wasn't added as arrayExtension as well.

Notes:

  • Node version needs to be update to a version that supports ECMAScript2023, however I can revert 227290d if this is not desired

Performance difference (Mac M1 air: plugged-in):

⚠️ not all tests are included in PR, results are not accurate and should be taken at face value, I didn't test that all functions have performance gains just one from every category of function and also these figures haven't been tested on different machines and conditions yet.

fn before after note
at (es2022) 0.25s min - 0.40s max 0.21s min - 0.26s max non significant performance gain
findLastIndex (mapLikeFunc) 2.91s min - 3.18s max 0.73s min - 1.08s max significant performance gain
toSorted and similar functions 3.59s min - 4.1s min 1.0s min - 1.3s max significant performance gain
with 3.06s min - 3.24s min 0.25s min - 0.28s max significant performance gain

Perf testing code:

at

  test(`${version} - array.es2023 at method`, function (t) {
        gc()
        let aCalc = 0
        const ar = observable([0])
        const firstElement = computed(function () {
            aCalc++
            return ar.at(0);
        })
        mobx.observe(firstElement, voidObserver, true)

        const start = now()

        t.equal(1, aCalc)
        for (let i = 1; i < 10000; i++) ar.push(i)

        t.equal(0, firstElement.get())
        t.equal(10000, aCalc)

        const end = now()

        log(
            "Array.at loop -  Updated in " + (end - start) + " ms."
        )
        t.end()
    })

findLastIndex - added to perf.js

toSorted

    test(`${version} - array.es2023 toSorted method`, function (t) {
        gc()
        let aCalc = 0
        const ar = observable([1])
        const sortedAr = computed(function () {
            aCalc++
            return ar.toSorted();
        })
        mobx.observe(sortedAr, voidObserver, true)

        const start = now()

        t.equal(1, aCalc)
        for (let i = 1; i < 10000; i++) ar.push(i)

        t.equal(0, sortedAr.get()[0])
        t.equal(10000, aCalc)

        const end = now()

        log(
            "Array.toSorted loop -  Updated in " + (end - start) + " ms."
        )
        t.end()
    })

with

 test(`with method`, function (t) {
        gc()
        let aCalc = 0
        const ar = observable([1])
        const arWithZero = computed(function () {
            aCalc++
            return ar.with(0, 0);
        })
        mobx.observe(arWithZero, voidObserver, true)

        const start = now()

        t.equal(1, aCalc)
        for (let i = 1; i < 10000; i++) ar.push(i)

        t.equal(0, arWithZero.get()[0])
        t.equal(10000, aCalc)

        const end = now()

        log(
            "Array.with loop -  Updated in " + (end - start) + " ms."
        )
        t.end()
    })

Copy link

changeset-bot bot commented Nov 11, 2023

🦋 Changeset detected

Latest commit: 227290d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
mobx Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@tonyraoul tonyraoul changed the title perf(observablearray): ECMAScript2023 & ECMAScript2022 array methods performance improvement for proxy perf: ECMAScript2023 & ECMAScript2022 array methods performance improvement for proxy Nov 11, 2023
@mweststrate
Copy link
Member

This is awesome! Thanks for the diligent P.R and tests!

@mweststrate mweststrate merged commit a2db19e into mobxjs:main Nov 25, 2023
1 check passed
This was referenced Nov 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants