Skip to content
New issue

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

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

Already on GitHub? # to your account

Faster insert for the index == len case #282

Merged
merged 2 commits into from
Jun 24, 2022

Conversation

nnethercote
Copy link
Contributor

@nnethercote nnethercote commented Jun 23, 2022

This case popped up within rustc, where insert was repeatedly used for a push-like operation. (But in a context where push wasn't always appropriate.) It speeds up rustc on one benchmark by 2% -- not huge, but also not bad for such a small change.

Here is some before and after results for the new benchmark along with the existing push benchmarks.

Old:

test bench_push                        ... bench:         317 ns/iter (+/- 25)
test bench_push_small                  ... bench:          34 ns/iter (+/- 1)
test bench_insert_push                 ... bench:         627 ns/iter (+/- 32)
test bench_insert_push_small           ... bench:          99 ns/iter (+/- 6)

New

test bench_push                        ... bench:         295 ns/iter (+/- 21)
test bench_push_small                  ... bench:          36 ns/iter (+/- 3)
test bench_insert_push                 ... bench:         504 ns/iter (+/- 17)
test bench_insert_push_small           ... bench:          70 ns/iter (+/- 4)

The first two are testing identical code, and show that the time variation is non-trivial. The latter two show the effect of this PR's code changes, which are well beyond the timing variation.

By skipping the call to `copy` with a zero length. This makes it closer
to `push`. This speeds up rustc (which uses `SmallVec` extensively) by
2% on one benchmark.

Also clarify the panic condition.
@nnethercote nnethercote requested a review from mbrubeck June 23, 2022 06:50
@nnethercote
Copy link
Contributor Author

This is the relevant use point within Rust, if you are curious.

@mbrubeck mbrubeck merged commit 7f9e513 into servo:master Jun 24, 2022
@mbrubeck
Copy link
Collaborator

Thanks! Released as v1.8.1: https://crates.io/crates/smallvec/1.8.1

@nnethercote nnethercote deleted the faster-insert branch June 25, 2022 03:09
nnethercote added a commit to nnethercote/rust that referenced this pull request Jun 26, 2022
This pulls in servo/rust-smallvec#282, which
gives some small wins for rustc.
bors added a commit to rust-lang-ci/rust that referenced this pull request Jun 29, 2022
Update `smallvec` to 1.8.1.

This pulls in servo/rust-smallvec#282, which
gives some small wins for rustc.

r? `@lqd`
nnethercote added a commit to nnethercote/rust that referenced this pull request Jul 1, 2022
By skipping the call to `copy` with a zero length. This makes it closer
to `push`.

I did this recently for `SmallVec`
(servo/rust-smallvec#282) and it was a big perf win in
one case. Although I don't have a specific use case in mind, it seems
worth doing it for `Vec` as well.

Things to note:
- In the `index < len` case, the number of conditions checked is
  unchanged.
- In the `index == len` case, the number of conditions checked increases
  by one, but the more expensive zero-length copy is avoided.
- In the `index > len` case the code now reserves space for the extra
  element before panicking. This seems like an unimportant change.
bors added a commit to rust-lang-ci/rust that referenced this pull request Jul 3, 2022
Optimize `Vec::insert` for the case where `index == len`.

By skipping the call to `copy` with a zero length. This makes it closer
to `push`.

I did this recently for `SmallVec`
(servo/rust-smallvec#282) and it was a big perf win in
one case. Although I don't have a specific use case in mind, it seems
worth doing it for `Vec` as well.

Things to note:
- In the `index < len` case, the number of conditions checked is
  unchanged.
- In the `index == len` case, the number of conditions checked increases
  by one, but the more expensive zero-length copy is avoided.
- In the `index > len` case the code now reserves space for the extra
  element before panicking. This seems like an unimportant change.

r? `@cuviper`
bjorn3 pushed a commit to rust-lang/rustc_codegen_cranelift that referenced this pull request Jul 3, 2022
This pulls in servo/rust-smallvec#282, which
gives some small wins for rustc.
workingjubilee pushed a commit to tcdi/postgrestd that referenced this pull request Sep 15, 2022
By skipping the call to `copy` with a zero length. This makes it closer
to `push`.

I did this recently for `SmallVec`
(servo/rust-smallvec#282) and it was a big perf win in
one case. Although I don't have a specific use case in mind, it seems
worth doing it for `Vec` as well.

Things to note:
- In the `index < len` case, the number of conditions checked is
  unchanged.
- In the `index == len` case, the number of conditions checked increases
  by one, but the more expensive zero-length copy is avoided.
- In the `index > len` case the code now reserves space for the extra
  element before panicking. This seems like an unimportant change.
workingjubilee pushed a commit to tcdi/postgrestd that referenced this pull request Sep 15, 2022
Optimize `Vec::insert` for the case where `index == len`.

By skipping the call to `copy` with a zero length. This makes it closer
to `push`.

I did this recently for `SmallVec`
(servo/rust-smallvec#282) and it was a big perf win in
one case. Although I don't have a specific use case in mind, it seems
worth doing it for `Vec` as well.

Things to note:
- In the `index < len` case, the number of conditions checked is
  unchanged.
- In the `index == len` case, the number of conditions checked increases
  by one, but the more expensive zero-length copy is avoided.
- In the `index > len` case the code now reserves space for the extra
  element before panicking. This seems like an unimportant change.

r? `@cuviper`
eddyb pushed a commit to LykenSol/rustc_apfloat-git-history-extraction that referenced this pull request Nov 14, 2022
This pulls in servo/rust-smallvec#282, which
gives some small wins for rustc.


[git filter-repo] original commit: rust-lang/rust@7c40661
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants