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

Use a Set for checking if an element is a void element, which is faster than object access #1468

Merged
merged 5 commits into from
Oct 27, 2023

Conversation

NullVoxPopuli
Copy link
Contributor

@NullVoxPopuli NullVoxPopuli commented Oct 27, 2023

When it comes to raw speed, for small datasets, Map.get is faster than Object[..] is faster than Set.has

benchmark - Map#get - key exists

benchmark - Map#get - key does not exist

builds on top of: #1467

benchmark - Map#has - key does not exist

benchmark - Map#has - key exists

@NullVoxPopuli NullVoxPopuli changed the title Use Map, which is faster than object access Use a Map for checking if an element is a void element, which is faster than object access Oct 27, 2023
@fisker
Copy link
Contributor

fisker commented Oct 27, 2023

It's slower on my machine.
You should also test non-exists tags in the benchmark, I think.

@NullVoxPopuli
Copy link
Contributor Author

good idea.

with non-existent-keys

It looks as if object wins out again.

so I'm going to leave this as an object.

@NullVoxPopuli NullVoxPopuli deleted the improve-perf-of-void-tag-lookup branch October 27, 2023 17:22
@fisker
Copy link
Contributor

fisker commented Oct 27, 2023

Map#has seems faster then Map#get

@NullVoxPopuli
Copy link
Contributor Author

that's curious. which makes for an interesting situation with this data structure, because using Map#has, makes the Map basically a Set, but Map performs way better than Set.
I wonder if that means browser vendors just haven't optimized Set as extensively yet?

@NullVoxPopuli NullVoxPopuli reopened this Oct 27, 2023
@chancancode
Copy link
Contributor

Generally in that package we don’t care about performance that much, at least not to that extent, since it typically only runs during the build, and of all the things that is slow in the build, it is not going to come down to these lookups. So just use whatever reads best and makes the most sense.

@chancancode
Copy link
Contributor

Also if this intended to be public then it’s probably better to export a function to check rather than exposing whatever underlying data structure

@NullVoxPopuli
Copy link
Contributor Author

well, I use @glimmer/syntax at runtime for REPL stuff 😅

@NullVoxPopuli
Copy link
Contributor Author

NullVoxPopuli commented Oct 27, 2023

Also if this intended to be public then it’s probably better to export a function to check rather than exposing whatever underlying data structure

that's PR #1467

@fisker how does prettier need to interact with this data?

@fisker
Copy link
Contributor

fisker commented Oct 27, 2023

We bundle them to JSON... 😄

@fisker
Copy link
Contributor

fisker commented Oct 27, 2023

@chancancode
Copy link
Contributor

Yeah then I think we just expose getVoidTags that returns an array and isVoidTag and keep the implementation private

Copy link
Contributor

@chancancode chancancode left a comment

Choose a reason for hiding this comment

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

looks good to me! fwiw, I don't know how "public" anything really is, so at some point, probably when we talk about restructuring the packages to simplify things, we probably want to be more rigorous about delineating the public api surface

@chancancode
Copy link
Contributor

well, I use @glimmer/syntax at runtime for REPL stuff 😅

I still doubt this is what is a hot path that makes it slow, but I can believe it if it shows up on benchmarks; anyway now that the implementation is private you are more free to tweak that if you find that necessary; if it ends up being that important, then I suspect the answer is neither Map nor Set, but perhaps a switch statement in the function where the tags or ordered from the most to least common, and you would probably add fast paths for things like div/p (the most common non-void tags) that returns false early without having to go through the rest.

@chancancode
Copy link
Contributor

But, in general, the performance profiles of these micro things changes over time and we don't have time to keep up with that, so we just end up with a lot of micro optimizations that we don't know if are still necessary or actively causing problems

function isVoidTag(tag: string): boolean {
return !!(voidMap[tag.toLowerCase()] && tag[0]?.toLowerCase() === tag[0]);
export function isVoidTag(tag: string): boolean {
return !!(voidMap.has(tag.toLowerCase()) && tag[0]?.toLowerCase() === tag[0]);
Copy link
Contributor

Choose a reason for hiding this comment

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

!! become useless.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks! I wasn't even looking at that -- more ancient code

@NullVoxPopuli NullVoxPopuli changed the title Use a Map for checking if an element is a void element, which is faster than object access Use a Set for checking if an element is a void element, which is faster than object access Oct 27, 2023
…t vs Map's perf differences are not important enough right now (since this is build-time code), and maintainability takes precedence in this case
@NullVoxPopuli NullVoxPopuli force-pushed the improve-perf-of-void-tag-lookup branch from 3a23a63 to f92a036 Compare October 27, 2023 19:15
@NullVoxPopuli
Copy link
Contributor Author

TIL !! in a string in bash is replaced with the previously ran command
image

@fisker
Copy link
Contributor

fisker commented Oct 27, 2023

Maybe this is a good chance to mention that several void tags actually missing.

https://github.com/prettier/prettier/pull/14110/files#diff-6faed7f5afc0a02a5e775622809f442bc831a1ac00bbb657cd08014962d5aebeR4

Someone may interest to in investigate.

If they are just missing by mistake, maybe we can switch to use html-void-elements package?

@fisker
Copy link
Contributor

fisker commented Oct 27, 2023

And it's funny, three of them removed in HTML spec... https://github.com/wooorm/html-void-elements/pull/7/files

@NullVoxPopuli
Copy link
Contributor Author

oh I like that
image

@chancancode I can do this switch in a separate PR so the PRs stay focused

@NullVoxPopuli NullVoxPopuli merged commit 9aabf21 into export-visitorKeys Oct 27, 2023
@fisker
Copy link
Contributor

fisker commented Oct 27, 2023

html-tags is even popular.. But I suggest use html-void-elements since the owner is more active in related projects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants