-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Optimise vtag #1447
Optimise vtag #1447
Conversation
This reverts commit 7c59c61.
Before I take a closer look at this, there are a few things I've noticed:
As a whole this looks very promising but this PR does a little too much in my opinion. |
I'll look into that.
Noted.
I might be misunderstanding the point of keys on VList then. Obvious what they are for on individual nodes but not quite for lists.
This PR is about reducing memory usage for VTag in general. I could separate static string usage, VTagInner and in-place construction into separate PRs, if needed. But I hardly see that as less work than reviewing one PR. |
The thing is that fragments (lists) can also be members of a list like so: html! {
<key="my-list">
<div />
<key="item in my list">
<span />
</>
<>
}
If you feel like splitting these up would be an unnecessary endeavour that's totally fine by me. Again, I haven't taken a closer look yet so I will take your word for it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few preliminary thoughts I have. The most important one is about using a Cow
.
@bakape these optimizations look very promising!
I also prefer separate PRs. It's not about "less work" as it is about reducing cognitive overhead. Also, some of your changes are simple and can get merged quickly, while others are more complex or controversial and require more thought. I personally can always find time for a 100 line PR, but rarely get time to fully review a 1000 line PR. It's definitely more work for you to split things up, but the alternative is this huge PR moves much more slowly. |
@jstarry Okay, I will then do as suggested and split this PR, starting with the static string optimisations. |
Co-authored-by: Teymour Aldridge <42674621+teymour-aldridge@users.noreply.github.com>
Co-authored-by: Teymour Aldridge <42674621+teymour-aldridge@users.noreply.github.com>
Co-authored-by: Teymour Aldridge <42674621+teymour-aldridge@users.noreply.github.com>
Just submitted the last round of feedback, once these comments are addressed we can merge. Thank you! |
Co-authored-by: Justin Starry <justin.m.starry@gmail.com>
Co-authored-by: Justin Starry <justin.m.starry@gmail.com>
Co-authored-by: Justin Starry <justin.m.starry@gmail.com>
Co-authored-by: Justin Starry <justin.m.starry@gmail.com>
Co-authored-by: Justin Starry <justin.m.starry@gmail.com>
Co-authored-by: Justin Starry <justin.m.starry@gmail.com>
@jstarry Done except for the attribute stderr regression. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So awesome, thank you so much for this!
I wasn't sure if these changes would impact the JS benchmarks but looks like they improved performance by about 5%! https://www.dropbox.com/s/k6uzlh20gyd9gsv/Screen%20Shot%202020-08-22%20at%207.24.14%20PM.png?dl=0 |
@bakape I just had another idea. What if we took static strings a step further? Right now we are using static strings for tag names but we have one static string per usage. It would be nice to reuse static strings. Example
This example currently uses 2 static "div" and 4 static "span". Yew could export static strings for all common elements and then the macro could substitute those so that we only need one static "div" and one static "span". Thoughts? |
@jstarry I have something similar to that planned as a So
becomes
Diffing those is much much faster, because it's just string comparison, and they are applied to the DOM via a single I also have a global event listener multiplexer in the works. |
@bakape cool! I think we could still have the proc macro help with tags with dynamic attributes as well by reusing string literals.
Woot, this is going to be the killer feature for performance I think. |
@jstarry Oh, I misunderstood what you meant in
Would be very suprised, if the compiler actually creates 2 identical static strings. Let me check. |
@jstarry It does not https://godbolt.org/z/1GbxPh |
Ah great, never mind then. I'll be sure to use godbolt more often, such a cool tool :) |
* yew/vtag: remove needless indirection * yew/vtag: reduce VTag memory footprint * Revert "yew/vtag: remove needless indirection" This reverts commit 7c59c61. * yew/vtag,yew-macro: optimise attribute setting and memory usage * yew/vtag,yew-macro: reduce string memory footprint and use static strings more * yew,yew-macro: opportunistically use static memory for VText * yew/vtag: use String instead of Box<str> * yew-macro: remove one extra iteration * yew/vtag: remove API extension for textarea * yew/vtag: remove extra calls * yew-macro: preconstruct StringRef for class literals * yew-macro: construct non-dynamic VTags in-place * yew-macro: Insert class and href into attrs in-place * *: run stable checks * yew/vtag: use key-pair vector for attributes * yew/macro,yew: use trait associated methods with paths, where possible * Update yew/src/virtual_dom/vtag.rs Co-authored-by: Teymour Aldridge <42674621+teymour-aldridge@users.noreply.github.com> * Update yew/src/virtual_dom/vtag.rs Co-authored-by: Teymour Aldridge <42674621+teymour-aldridge@users.noreply.github.com> * Update yew/src/virtual_dom/vtag.rs Co-authored-by: Teymour Aldridge <42674621+teymour-aldridge@users.noreply.github.com> * Update yew/src/virtual_dom/vtag.rs Co-authored-by: Teymour Aldridge <42674621+teymour-aldridge@users.noreply.github.com> * Update yew/src/virtual_dom/vtag.rs Co-authored-by: Teymour Aldridge <42674621+teymour-aldridge@users.noreply.github.com> * Update yew/src/virtual_dom/vtag.rs Co-authored-by: Teymour Aldridge <42674621+teymour-aldridge@users.noreply.github.com> * yew/vtag: comment clarification as suggested by @teymour-aldridge * yew/vtag: fix added test failing * yew/vlist: revert removing key * yew/vtag,yew-macro: stash VTagInner changes for later * yew/vtag: restore diff_attributes() generating a patch list + add bechmarks * yew: fix becnhmarks running with std_web * yew: remove Href * yew/vtag: fix comment changes * examples: fix trait impl * yew: swap Stringref with Cow * examples: remove redundant clone * ci: fix stable check * yew/VText: remove needless constructor * *: remove needless trait full paths * yew/benchmarks: add IndexMap attribute diff becnhmark * yew-macro: fix stderr regressions * yew: convert Attributes to enum with variants optimised for both the html! macro and the VTag API * yew/benchmarks: move feature guard * Update examples/common/src/markdown.rs Co-authored-by: Justin Starry <justin.m.starry@gmail.com> * Update examples/common/src/markdown.rs Co-authored-by: Justin Starry <justin.m.starry@gmail.com> * Update examples/common/src/markdown.rs Co-authored-by: Justin Starry <justin.m.starry@gmail.com> * Update examples/common/src/markdown.rs Co-authored-by: Justin Starry <justin.m.starry@gmail.com> * Update examples/common/src/markdown.rs Co-authored-by: Justin Starry <justin.m.starry@gmail.com> * examples: remove unused import * Apply suggestions from code review Co-authored-by: Justin Starry <justin.m.starry@gmail.com> * yew-macro: rebuild stderr * yew-macro: accept Into<Cow> for dynamic tags * yew-macro: remove unneeded {} wrapping * yew: revert doc comment * yew/vtag: clean up attribute type conversion * yew-macro: remove now supported literal failures Co-authored-by: Teymour Aldridge <42674621+teymour-aldridge@users.noreply.github.com> Co-authored-by: Justin Starry <justin.starry@icloud.com> Co-authored-by: Justin Starry <justin.m.starry@gmail.com>
Description
Optimized overall performance of VTag operations, mostly focusing on speeding up construction, reducing allocations and memory footprint.
Optimizations
yew-macro
to detect literals in most cases. These are set inVTag
as static lifetime strings and thus notably reduce the need to allocateString
s (depends on HTML parametrization level). These include:VText
contentsVtag
, by excluding impossible used field combinations using an enum.key
fromVList
. Arguably a very niche feature that still increased the memory footprint ofVList
and anything using it by 3 words.VTag
construction viayew-macro
Vec
of key-value pairs. This has the benefit of not needing to constructHashMap
s onVTag
construction and that most scenarios will not encounter a change in attribute list length and key order.VTags
to enable the compiler to more eagerly optimise out encased calls.Breaking changes
VTag
construction can create previously not present moved value usage conflicts.key
fromVList
.kind
attribute fromVTag
. It's use cases are now fully covered with thetype
attribute.Checklist:
./ci/run_stable_checks.sh