-
Notifications
You must be signed in to change notification settings - Fork 195
Extract inner function from half-join #619
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
Extract inner function from half-join #619
Conversation
Signed-off-by: Moritz Hoffmann <[email protected]>
Signed-off-by: Moritz Hoffmann <[email protected]>
45ba04b
to
38f6fb5
Compare
*diff1 = R::zero(); | ||
} | ||
} | ||
yielded |= process_proposals::<G, _, _, _, _, _, _, _, _>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd love to avoid relying short-circuited evaluation if at all possible. Mostly from a clarity point of view.
816ec43
to
9cea5a8
Compare
Signed-off-by: Moritz Hoffmann <[email protected]>
9cea5a8
to
f604faa
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is mergeable, but I also think it reveals that the file is at a bursting point from a readability / clarity point of view. We should do no further changes without some clean-up.
/// Process proposals one at a time, yielding if necessary. | ||
/// | ||
/// Returns `true` if the operator should yield. | ||
/// | ||
/// Utility function for `half_join_internal_unsafe`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new layout confuses me, and I think it's partly that the comment used to be on a for-loop, where I could understand what we were talking about wrt "one at a time, yielding if necessary". Now it's a method, and .. it's totally unclear what this means.
This might just be Rust being awkward around refactoring, where the absolute wall of captured state is .. necessary, but utterly inexplicable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The signature and constraints are almost (20 lines) as long as the method body (30 lines).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the tl;dr is that this probably needs a real refactoring, which I'm happy to do, whereas this is more a tear-out. My understanding is that this is for performance more than anything, because Rust/LLVM is unwilling to perform the intended inlining in complex code blocks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like with the type
above, perhaps the best documentation here is just
/// Outlining of the inner loop of `half_join_internal_unsafe` for reasons of performance.
.as_collection() | ||
} | ||
|
||
/// Utility type for a session in scope `G` with a container builder `CB`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I propose we aim for a better comment here. Yes it is a utility type, but that does not clarify what it is for, how you should hold it, etc. In particular, I'd stress that this is just a shortening of a type for readability. I think potentially a better (imo) comment would just be
/// A shorthand for an otherwise complex type describing a session with lifetime `'a` in a scope `G` with a container builder `CB`.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe flipped around a bit to be
/// A session with lifetime `'a` in a scope `G` with a container builder `CB`.
///
/// This is a shorthand primarily for purposes of readability.
Signed-off-by: Moritz Hoffmann <[email protected]>
Signed-off-by: Moritz Hoffmann <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Thank you.
Extract the inner loop of half-join into a separate function.
This change extracts the inner loop across
proposals
in half-join into a separate function. The idea is that the inner loop is hot, but by embedding it in the closure, the optimizer has a hard time inlining functions called from within the loop on account of the size of the closure itself. Help the optimizer by extracting the hot loop in the hope that this enables better inlining.Also some changes around the return type of the
half_join_internal_unsafe
function. Instead of forcing a stream of vectors, allow the caller to provide a container builder, and return a stream instead. (We could return a collection, but the caller can do that themselves easily enough.)