-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Implement special min/max accumulator for Strings and Binary (10% faster for Clickbench Q28) #12792
Conversation
65f1b65
to
8cd03ac
Compare
8cd03ac
to
8bc00f8
Compare
I need to write some more specific / targeted tests here and we'll be ready for review |
fn set_value(&mut self, group_index: usize, new_val: &[u8]) { | ||
match self.min_max[group_index].as_mut() { | ||
None => { | ||
self.min_max[group_index] = Some(new_val.to_vec()); |
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 wonder if it makes sense to overallocate a bit here to avoid reallocations (e.g. 2x the size, or using a statistic, e.g. (total_data_bytes / min_max.len()) * factor
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 can try it -- with this change the time spent in this accumulator becomes very small (like < 1% in the traces). I will try it anyways
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.
Testing in #12845
/// groups in an individual byte array, which balances allocations and memory | ||
/// fragmentation (aka garbage). | ||
/// | ||
/// ```text |
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.
Here is the diagram of this design
@@ -3818,6 +3818,180 @@ DROP TABLE min_bool; | |||
# Min_Max End # | |||
################# | |||
|
|||
|
|||
|
|||
################# |
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 will also make another PR to update the AggregateFuzz test added by @Rachelint in #12667 to cover these scenarios as well
/// Replaces the nulls in the input array with the given `NullBuffer` | ||
/// | ||
/// Can replace when upstreamed in arrow-rs: <https://github.com/apache/arrow-rs/issues/6528> | ||
pub fn set_nulls_dyn(input: &dyn Array, nulls: Option<NullBuffer>) -> Result<ArrayRef> { |
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 is supporting code for replacing the null buffers in arrays
Ok, I think this is now ready to review |
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.
👍
Thank you for the reviews @jayzhan211 and @Dandandan I plan to merge this tomorrow to give other people a chance to review it if they would like |
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.
(skimming)
datafusion/functions-aggregate-common/src/aggregate/groups_accumulator/nulls.rs
Outdated
Show resolved
Hide resolved
/// Replaces the nulls in the input array with the given `NullBuffer` | ||
/// | ||
/// Can replace when upstreamed in arrow-rs: <https://github.com/apache/arrow-rs/issues/6528> | ||
pub fn set_nulls_dyn(input: &dyn Array, nulls: Option<NullBuffer>) -> Result<ArrayRef> { |
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.
nit: this could be private
_ => { | ||
return not_impl_err!("Applying nulls {:?}", input.data_type()); |
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.
Do we have to support this for any other data types?
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.
not necessairly -- I am hoping we put this code upstream in arrow-rs and can remove it entirely from datafusion eventually
/// ┌─────────────────────────────────┐ | ||
/// ┌─────┐ ┌────▶│Option<Vec<u8>> (["A"]) │───────────▶ "A" | ||
/// │ 0 │────┘ └─────────────────────────────────┘ | ||
/// ├─────┤ ┌─────────────────────────────────┐ | ||
/// │ 1 │─────────▶│Option<Vec<u8>> (["Z"]) │───────────▶ "Z" | ||
/// └─────┘ └─────────────────────────────────┘ ... | ||
/// ... ... | ||
/// ┌─────┐ ┌────────────────────────────────┐ | ||
/// │ N-2 │─────────▶│Option<Vec<u8>> (["A"]) │────────────▶ "A" | ||
/// ├─────┤ └────────────────────────────────┘ | ||
/// │ N-1 │────┐ ┌────────────────────────────────┐ | ||
/// └─────┘ └────▶│Option<Vec<u8>> (["Q"]) │────────────▶ "Q" | ||
/// └────────────────────────────────┘ | ||
/// | ||
/// min_max: Vec<Option<Vec<u8>> |
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.
nice!
🚀 |
…ter for Clickbench Q28) (apache#12792) * Implement special min/max accumulator for Strings: `MinMaxBytesAccumulator` * fix bug * fix msrv * move code, handle filters * simplify * Add functional tests * remove unecessary test * improve docs * improve docs * cleanup * improve comments * fix diagram * fix accounting * Use correct type in memory accounting * Add TODO comment
Which issue does this PR close?
Closes #6906
Rationale for this change
Ensure we can turn on StringView -- see #6906. Also bonus make some queries faster
What changes are included in this PR?
Are these changes tested?
Yes -- new functional tests
Performance
3x faster for some pathological queries)
For this query defined in #6906 (comment)
Run via
datafusion-cli -f q28.sql
Elapsed 18.549 seconds.
Elapsed 6.187 seconds.
10% faster for normal ClickBench Q28
Q28 (with
MIN("Referrer")
also gets slightly faster:Total results:
Are there any user-facing changes?
Slightly faster performance