Skip to content

Avoid a temporary allocation when reporting frontiers#20904

Merged
antiguru merged 1 commit into
MaterializeInc:mainfrom
antiguru:compute_state_temp_allocation
Aug 1, 2023
Merged

Avoid a temporary allocation when reporting frontiers#20904
antiguru merged 1 commit into
MaterializeInc:mainfrom
antiguru:compute_state_temp_allocation

Conversation

@antiguru

@antiguru antiguru commented Aug 1, 2023

Copy link
Copy Markdown
Member

Motivation

Fixes an unreported issue. We're allocating a new Antichain for every maintained collection when reporting frontiers. With this PR, we re-use the allocation, avoiding a significant number of temporary allocations.

It's hard to say what performance impact this has, but it's good habit to avoid allocations if it's easy to do.

Checklist

  • This PR has adequate test coverage / QA involvement has been duly considered.
  • This PR has an associated up-to-date design doc, is a design doc (template), or is sufficiently small to not require a design.
  • If this PR evolves an existing $T ⇔ Proto$T mapping (possibly in a backwards-incompatible way), then it is tagged with a T-proto label.
  • If this PR will require changes to cloud orchestration, there is a companion cloud PR to account for those changes that is tagged with the release-blocker label (example).
  • This PR includes the following user-facing behavior changes:

Signed-off-by: Moritz Hoffmann <mh@materialize.com>
@antiguru antiguru requested review from a team and teskje August 1, 2023 12:21
}

new_uppers.push((id, new_frontier));
new_uppers.push((id, new_frontier.clone()));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Now we avoid the allocation above but need to .clone() here. How is this different in terms of memory footprint?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Most of the iterations don't even get here because we only report changes.

let mut new_uppers = Vec::new();

// Maintain a single allocation for `new_frontier` to avoid allocating on every iteration.
let mut new_frontier = Antichain::new();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No strong feelings, but I'd like to call out that this reverts a suggestion you made here: #20090 (comment) :D

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, I know! Sorry for that, and it's also why I added a comment so we don't forget!


for (&id, collection) in self.compute_state.collections.iter_mut() {
let mut new_frontier = Antichain::new();
new_frontier.clear();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't think clearing is necessary here, based on that before #20090 it also didn't happen. Presumably both read_upper and clone_from do their own clears.

While writing this I have convinced myself that this is still a good thing to do, as a matter of defensive programming. So feel free to disregard this :)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yup, you're correct, but I added it to not confuse myself again that there is any important state maintained across loop iterations.

@antiguru antiguru merged commit 2655020 into MaterializeInc:main Aug 1, 2023
@antiguru antiguru deleted the compute_state_temp_allocation branch August 1, 2023 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants