Skip to content

Conversation

@webbeef
Copy link
Contributor

@webbeef webbeef commented Nov 21, 2025

This saves the work done by 'ptr::read()' that we don't use.

Testing: Green WPT run: https://github.com/webbeef/servo/actions/runs/19560614891

@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Nov 21, 2025
Copy link
Member

@yezhizhen yezhizhen left a comment

Choose a reason for hiding this comment

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

This is O(1) already. Is this really necessary?

@Taym95
Copy link
Member

Taym95 commented Nov 21, 2025

This is O(1) already. Is this really necessary?

also worth replacing it with unsafe code?

@simonwuelker
Copy link
Contributor

Thanks for your performance investigation work! Does this improve any benchmarks? I wouldn't be surprised if the compiler already performed this optimization.

@webbeef
Copy link
Contributor Author

webbeef commented Nov 21, 2025

Thanks for your performance investigation work! Does this improve any benchmarks? I wouldn't be surprised if the compiler already performed this optimization.

I spotted the ptr::read done in Vec::swap_remove() in some profiles. The perf improvements are variable (I've seen better results on Mac than Linux for some reason) and not huge for sure in terms of wall time. That mostly moves the hot path somewhere else.

Some(idx) => {
roots.swap_remove(idx);
unsafe {
let len = roots.len() - 1;
Copy link
Member

Choose a reason for hiding this comment

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

This can overflow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

why? If we are in this branch, we found a match so roots.len() >= 1 and then len >= 0 . Or am I missing something?

Copy link
Member

Choose a reason for hiding this comment

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

You are right. I was checking this only with https://doc.rust-lang.org/src/alloc/vec/mod.rs.html#2048 in mind without considering too much context.

let base_ptr = roots.as_mut_ptr();
ptr::copy_nonoverlapping(base_ptr.add(len), base_ptr.add(idx), 1);
}
roots.set_len(len);
Copy link
Member

Choose a reason for hiding this comment

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

We shouldn't set new length here. It should be part of above if block.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I disagree: we always need to update the length, but we can skip the copy/move when the match it the last element.

Copy link
Member

Choose a reason for hiding this comment

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

Indeed!

Copy link
Member

@yezhizhen yezhizhen left a comment

Choose a reason for hiding this comment

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

I was being sloppy.

Some(idx) => {
roots.swap_remove(idx);
unsafe {
let len = roots.len() - 1;
Copy link
Member

Choose a reason for hiding this comment

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

You are right. I was checking this only with https://doc.rust-lang.org/src/alloc/vec/mod.rs.html#2048 in mind without considering too much context.

Copy link
Member

@yezhizhen yezhizhen left a comment

Choose a reason for hiding this comment

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

also worth replacing it with unsafe code?

This is fine as it is what the original swap_remove do. User is held accountable to the usage of it to not panic.

And for our case, we're guaranteed to never panic.

@servo-highfive servo-highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Nov 25, 2025
Copy link
Member

@jdm jdm left a comment

Choose a reason for hiding this comment

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

I think there's an opportunity to move this code into a reusable function that can be called from some other code with similar usage patterns, but I'll file an issue about that.

This saves the work done by 'ptr::read()' that we don't use.

Signed-off-by: webbeef <me@webbeef.org>
@webbeef webbeef force-pushed the unroot-manual-swap-remove branch from 4742d67 to b7120a8 Compare November 30, 2025 08:03
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Nov 30, 2025
@jdm jdm added this pull request to the merge queue Nov 30, 2025
@servo-highfive servo-highfive added the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Nov 30, 2025
Merged via the queue into servo:main with commit 414b254 Nov 30, 2025
32 checks passed
@servo-highfive servo-highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Nov 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-awaiting-review There is new code that needs to be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants