Uh oh!
There was an error while loading. Please reload this page.
Overhaul syntax::fold::Folder. - #58061
Conversation
nnethercote
commented
Feb 1, 2019
@bors try |
bors
commented
Feb 1, 2019
⌛ Trying commit b4a6b98fb425e66926941efa55dce39aea400914 with merge 4d27e368a336fc53353c891ee0dc425399c612c0... |
petrochenkov
commented
Feb 1, 2019
@nnethercote |
bors
commented
Feb 2, 2019
☀️ Test successful - checks-travis |
nnethercote
commented
Feb 2, 2019
I hadn't seen #57662. It's definitely overlapping with this PR. Notable differences, judging from a quick skim:
|
nnethercote
commented
Feb 2, 2019
The reason the new approach is faster is that an existing noop fold overwrites all the nodes with the same values. There are no reallocations due to the use of |
nnethercote
commented
Feb 2, 2019
@rust-timer build 4d27e368a336fc53353c891ee0dc425399c612c0 |
rust-timer
commented
Feb 2, 2019
Success: Queued 4d27e368a336fc53353c891ee0dc425399c612c0 with parent 23d8d0c, comparison URL. |
rust-timer
commented
Feb 2, 2019
Finished benchmarking try commit 4d27e368a336fc53353c891ee0dc425399c612c0 |
nnethercote
commented
Feb 2, 2019
The perf results are similar to what I saw locally. Widespread improvements, mostly on "clean incremental" runs, with a best result of -3.4%. |
nnethercote
commented
Feb 2, 2019
Comparing this PR with #57662 some more, the handling of the The handling of the other cases is where the differences are bigger. This PR keeps the existing structure for ones like In contrast, #57662 introduces the |
nnethercote
commented
Feb 2, 2019
A final summary! This PR:
Overall, I think this PR is more complete while involving less changes. But I'm biased :) Let me know if I've gotten any of the details wrong. |
b4a6b98 to
d05b178Comparennethercote
commented
Feb 4, 2019
I have updated the code. It's now complete except for one thing: as the "njn:" comment in the code says, I think the r? @petrochenkov: the code is ready to review, but as well as making the main change, I have made a bunch of minor clean-ups. If you like I could pull out those clean-ups into separate commits preceding the main commit. |
petrochenkov
commented
Feb 4, 2019
Great work, thanks. I think I prefer this PRs trajectory. Why:
|
Regarding naming. |
petrochenkov
commented
Feb 4, 2019
If that's not too annoying, could you split the PR into two commits
|
d05b178 to
f9d6e3eCompareSpecifically: - Remove dead methods: fold_usize, fold_meta_items, fold_opt_bounds. - Remove useless methods: fold_global_asm, fold_range_end. - Inline and remove unnecessary methods: fold_item_simple, fold_foreign_item_simple.
It doesn't need to return an `Option`.
It's simpler that way.
By eliminating some unnecessary methods, and moving/renaming some functions that look like they might be methods but aren't.
f9d6e3e to
3263f02Comparennethercote
commented
Feb 5, 2019
@petrochenkov: the new code is up.
|
petrochenkov
commented
Feb 5, 2019
The usual solution is to move the file renaming into a separate commit. |
petrochenkov
commented
Feb 5, 2019
r=me with the file renaming moved into a separate commit or without it. |
This commit changes `syntax::fold::Folder` from a functional style
(where most methods take a `T` and produce a new `T`) to a more
imperative style (where most methods take and modify a `&mut T`), and
renames it `syntax::mut_visit::MutVisitor`.
The first benefit is speed. The functional style does not require any
reallocations, due to the use of `P::map` and
`MoveMap::move_{,flat_}map`. However, every field in the AST must be
overwritten; even those fields that are unchanged are overwritten with
the same value. This causes a lot of unnecessary memory writes. The
imperative style reduces instruction counts by 1--3% across a wide range
of workloads, particularly incremental workloads.
The second benefit is conciseness; the imperative style is usually more
concise. E.g. compare the old functional style:
```
fn fold_abc(&mut self, abc: ABC) {
ABC {
a: fold_a(abc.a),
b: fold_b(abc.b),
c: abc.c,
}
}
```
with the imperative style:
```
fn visit_abc(&mut self, ABC { a, b, c: _ }: &mut ABC) {
visit_a(a);
visit_b(b);
}
```
(The reductions get larger in more complex examples.)
Overall, the patch removes over 200 lines of code -- even though the new
code has more comments -- and a lot of the remaining lines have fewer
characters.
Some notes:
- The old style used methods called `fold_*`. The new style mostly uses
methods called `visit_*`, but there are a few methods that map a `T`
to something other than a `T`, which are called `flat_map_*` (`T` maps
to multiple `T`s) or `filter_map_*` (`T` maps to 0 or 1 `T`s).
- `move_map.rs`/`MoveMap`/`move_map`/`move_flat_map` are renamed
`map_in_place.rs`/`MapInPlace`/`map_in_place`/`flat_map_in_place` to
reflect their slightly changed signatures.
- Although this commit renames the `fold` module as `mut_visit`, it
keeps it in the `fold.rs` file, so as not to confuse git. The next
commit will rename the file.3263f02 to
bfcbd23Comparennethercote
commented
Feb 5, 2019
Thank you for the suggestion, I did that. @bors r=petrochenkov |
bors
commented
Feb 5, 2019
📌 Commit bfcbd23 has been approved by |
bors
commented
Feb 6, 2019
…nkov Overhaul `syntax::fold::Folder`. This PR changes `syntax::fold::Folder` from a functional style (where most methods take a `T` and produce a new `T`) to a more imperative style (where most methods take and modify a `&mut T`), and renames it `syntax::mut_visit::MutVisitor`. This makes the code faster and more concise.
bors
commented
Feb 6, 2019
☀️ Test successful - checks-travis, status-appveyor |
Uh oh!
There was an error while loading. Please reload this page.
Make `visit_clobber`'s impl safe This was originally introduced in rust-lang#58061 but I didn't see any perf discussion about it, so let's see what perf says. r? `@nnethercote`
Make `visit_clobber`'s impl safe This was originally introduced in rust-lang#58061 but I didn't see any perf discussion about it, so let's see what perf says. r? `@nnethercote`
This PR changes
syntax::fold::Folderfrom a functional style(where most methods take a
Tand produce a newT) to a moreimperative style (where most methods take and modify a
&mut T), andrenames it
syntax::mut_visit::MutVisitor.This makes the code faster and more concise.