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

Updated Voby to 0.2.0 #1011

Merged
merged 10 commits into from
Mar 13, 2022
Merged

Updated Voby to 0.2.0 #1011

merged 10 commits into from
Mar 13, 2022

Conversation

fabiospampinato
Copy link
Contributor

I implemented a few optimizations here and there, maybe they'll make a measurable difference in the benchmark 🤔

@fabiospampinato
Copy link
Contributor Author

fabiospampinato commented Mar 6, 2022

v0.3.0 has a pretty amazing optimization, I'm very excited to see that in the benchmark!

@fabiospampinato
Copy link
Contributor Author

fabiospampinato commented Mar 6, 2022

From running the benchmark locally it looks like the benchmark doesn't quite measure this area much, so the optimization doesn't make much of a difference in the benchmark 😢 It'd be great if a "replace all rows" test but with 10k rows were added, it seems to be missing currently.


IMO how long it takes to replace nodes is much more important than how long it takes to create them, like if a list never changes it doesn't matter much if some framework is 2x slower at creating it, but if the list changes (like when scrolling a windowed one or something) it's important to measure how long it takes to get that updated. Currently the benchmark seems instead to be measuring for creation twice but for replacement once, which seems to bias the benchmark toward the less important side.

I think it would be useful to make these changes:

  • Add a "replace all rows" test with 10k rows.
  • Increase the number of replacements triggered in "replace all rows" tests from 1 to 3 maybe, since if something is replaced it's unlikely that it will replaced once, probably 3 is too low even.

@fabiospampinato
Copy link
Contributor Author

Shipped another batch of tweaks and optimizations.

@krausest if possible it'd be awesome to get this merged before the results table is refreshed for Chrome 100 🙏

@fabiospampinato
Copy link
Contributor Author

fabiospampinato commented Mar 10, 2022

Expanding on the issue of the benchmark being somewhat creation-biased:

  • The "append" test is also mainly measuring creation at the end of the day, as that's much more expensive than the diffing.
  • The "clear rows" test is kind of giving bad results if nodes are reused, because if they can be reused there's a bit more work to do to recycle them, while if you can just throw them away it would be faster, the thing is recycling nodes ends up giving you much better performance at runtime when it matters, but that's almost entirely not measured by this benchmark, except for the "replace 1000 rows" test.

Basically it'd be nice if the benchmark measured more things similar to runtime performance, like complex edits that happen without refreshing the browser in between.

@fabiospampinato
Copy link
Contributor Author

I'm getting some promising results locally with the last build. There were a handful of missing optimizations and some useless work that the previous builds were doing.

@krausest krausest added the merging started merging started (no more updates please) label Mar 13, 2022
@krausest krausest merged commit 3e56eff into krausest:master Mar 13, 2022
@krausest krausest removed the merging started merging started (no more updates please) label Mar 13, 2022
@krausest
Copy link
Owner

Screenshot from 2022-03-13 12-55-12
A nice improvement!

@krausest
Copy link
Owner

There one catch though. I think voby keeps the selected state on the row and not on the table. Thus I had to add note #800 .
Could you try to store the selected row in the model and then set the danger-class for the row that's equal to the selected row in the row render loop?

@fabiospampinato
Copy link
Contributor Author

Nice! Thanks for merging.

There's at least one more little optimization that would be worth implementing. Other than that one I'm running out of ideas though.

Could you try to store the selected row in the model and then set the danger-class for the row that's equal to the selected row in the row render loop?

Sure, I can do that 👍

$data ( [...data.slice ( 0, index ), ...data.slice ( index + 1 )] );
const index = data.findIndex ( datum => datum.id === id );
if ( index === -1 ) return;
$data ( data.slice ( 0, index ).concat ( data.slice ( index + 1 ) ) );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fabiospampinato would the shorter .splice() be any slower?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@leeoniya I'm not sure, it might depend on where the deletion happens.

I went with slice/concat because I need to make a new array to have the observable detect it as a change so that it can notify all its subscribers. But now that I think about it it would probably be better to expose the method for notifying subscribers, so that I can just edit the array in place and notify them manually.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure the notification route would have any measurable effect in this specific case, but good to have as option in voby.

for this bench i'd probably leave it written as-is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might shave 1ms or so, but more importantly it would make the code cleaner.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but more importantly it would make the code cleaner.

unless it's mutate & notify in some places, and shallow copy in other places :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unless it's mutate & notify in some places, and shallow copy in other places :)

A little messy, but cleaner than what the code looks like now. For the cleanest code when working with non-trivial data structures I think we ideally want to wrap the data structure in a proxy and extract observables out of it automatically, or something like that. I have another library for that but I haven't wired it with this one, it should be doable 🤔

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.

3 participants